Patents Are Going To Change

Within about two months time from the publication of this post, the patent for the portable computer is going to expire. Considering the proliferation of laptops, and the amount of patents involved with the manufacture of one, it’s hard to predict whether this change is going to affect the industry to any extent. However, this does illuminate clearly the point in time we’re in within these early stages of the age of information. It’s well known that the patentability of software was established within the U.S during the early 90’s, and that they’ve been growing in numbers ever since. This is important for us, because these days the first few batches of computer related patents are being released for free use. It is the unique character of this industry that makes this advancement un-newsworthy, because of a perceived pace of progress under which nothing of 20 years of age could be of any worth. Anyone who’s been around that long, though, knows this to be untrue. Innovation works much the same as a pendulum, moving from one extreme to the other. Such is the way Anil Dash describes the move from mainframes to the personal computer as a revolution of sorts, only to be followed by a swing of the pendulum in the opposite direction with the proliferation of the cloud. The same could be claimed with regard to IDEs, visual programming languages, imperative programming paradigms, and many other aspects of technology that we consider as innovative. Today’s world of technology is without a doubt on the move forward, but much of the conceptual foundations of today’s inventions were already laid out in legal speak in a previous turn of the wheel. This has the dual effect of allowing us to move forward in fronts that were blocked from extensive (as opposed to intensive) progress up to now, and also, limiting the possibility of a future appropriation of these innovations.

The Opportunity

When speaking of an extensive progress that weren’t possible up to now, one can imagine a world of smaller and smaller manufacturers, much like the way every town had it’s own bread makers and shoe makers at some point in time. This might seem counter-intuitive with regard to a common rationale of centralized manufacturing that can cuts costs, but this isn’t really the case in most industries. Nike has centralized manufacturing, but their products cost a fortune, because they have vast expenses for the purpose of brand building, and because there’s enough of a demand to make it worthwhile. The telecommunications equipment industry is another kind of example. A few manufacturers like Cisco have vast expenses in R&D and they aim for the higher end of the market. However, most of the consumers are service providers in developing nations, where infrastructure has yet to be deployed. In these markets there seems to be a clear preference for smaller manufacturers that provide cheaper goods. Another result of the same process could be better kinds of free software alternatives to existing products, and in particular a preference for maker alternatives or pretail variations that could replace the mass-manufactured goods of today’s world. The rise of 3D printing and maker culture saw an instantaneous reaction from IP aficionados that claimed for the need to implement IP protection mechanisms within printers, even for non-commercial use. But the expiration of patents for much of the technologies that are simple enough to be of relevance to makers would change the balance of power in these regards.

The Future Of Patents

Today’s innovative sphere is advanced in two parallel trajectories. On the one hand are entrepreneurs, hackers and makers, and on the other, a narrow oligopoly of tech giants. In a recent talk with Israel Twito, CEO of New-tone Patent Search ltd., it was noted that the same balance of power between big manufacturers that prevents smaller players from being able to compete, has the double-sided effect of forcing these same companies to continue the arms race forward, with intensive R&D, as well as through the constant acquisition of smaller players. When passing criticism over an exits-focused startup culture, one has to keep this state of affairs in mind. Some industries are blocked from entry to anyone that isn’t deep-pocketed enough to join into an arms race that’s already under way. On the other side of the market are big players that need sources of producing new IP, with little or no regard to the cost – both the financial one, and the one that has to do with the damage to innovation and to clients of acquired ventures. This saddening state has an upside as well, one that will only begin to show within the next few years. The tech giants are arming themselves with patents for their own ends, but are also making the patent system obsolete by way of doing so. With the realization that a patent’s strength lies in the abstractedness and generalization of its phrasing, and with the constant swings of the technological pendulum, we’ll see more and more areas where the field for innovation is ironically already covered by existing, expired patents. With that process underway, the tech giants of today will be forced to create products of such sophistication that their target audiences will narrow, much like Cisco’s does today.

An End Note

The grinding of the patent system by economically motivated and heavily funded players requires new and better tools to help us understand what opportunities lie before us. A survey of U.S patents that are about to expire within the next year shows interesting things like cloaking systems, software protection machanisms, electric car chargers, pen-based computer inputs, home networking, and a lot of the technologies around cellular communications. Crossing that information with patent lawsuit databases shows that not a lot of today’s expiring patents are inhibitors to innovation (or competition), but that’s going to change at some point in time, and we best be prepared.

My Cofounder Video Marketing Endeavors

I prepared a short wanted ad for my next venture with the kind help of my beloved partner. It got me to the first page of Youtube’s search results for the keyword “find a cofounder” with just friends and family marketing. It didn’t get me a cofounder. This indicates some relatively obvious conclusions: (1) There’s ad arbitrage on Youtube, and (2) this doesn’t matter if your target audience isn’t looking for you over there. Either way, here it is:

PinMyScreen – Bookmarks Using Pinterest

PinMyScreen is a Social bookmarking extension for Google Chrome. The extension adds a Pinterest pin button to the browser’s toolbar, and allows the user to pin website screenshots onto his Pinterest boards. This works the same way as with gimme bar only it doesn’t impose a new system on clients. Instead, PinMyScreen allows you to use your existing Pinterest acocunts to save your favorite websites.

Known Issues

PinMyScreen uses Chrome’s built-in screenshot functionality (the same one that’s used for the ‘most visited’ page you see when opening a new tab. This, for security reasons, prevents us from screenshoting any sensitive data that might exist within secured pages or Chrome web applications. As a result, not every website can be shot, and you’ll sometimes find that the extension sends an empty image onto the Pinterest ‘pin this’ form. The process of screenshoting a webpage requires a roundtrip request and response with our server. You should note that we do not keep any images or any other sort of information on those servers or anywhere else. As opposed to many other Chrome extensions, I’ve chosen not to use anonymous analytics as well, so no data on your actions is logged at any stage. However, communication with our servers sometimes takes a bit longer than expected. You should note, that if you clicked the ‘pin this’ button on your browser’s toolbar, the request was sent and the pinterest form will appear in a few seconds time. This however doesn’t always happen fast enough, and there isn’t an indication that the request is in a processing state. If I’ll hear a lot of complaints from people about speed, I’ll transfer the servers onto Amazon’s cloud services, so if you think that there’s place for improvement, just let me know.

Bug Reporting and Support

I’m always available to hearing feedback over the extension, be it a positive or negative one, so don’t hesitate. If there’s anything you need help with, just send me an email to me at shayacrich dot com.   Visit our page on the Chrome WebStore to add the extension to your browsers.

Guidelines for hiring someone to build your startup

1. You should have a very clear understanding of what you need built. Usually, mocking up the wireframes and writing a short spec that specifies the processes users go through in the system is a crucial first step. If you can’t do this yourself, the developer or team you work with will have to be experienced with doing this for entrepreneurs, but I definitely do recommend you try to do this yourself. 2. The developer or firm you work with should issue a detailed estimation and timeline, so that you’ll have a clear view of what’s going to happen. This will allow you to change course during development if you feel the work isn’t progressing in the right pace or if you need to change the requirements once you start to see your vision realized in code. 3. You should make sure that you’ll have the ability to track the work on a weekly basis, or sit with the developer in the same room. This means you know at any given point in time how many hours were already spent, and how many features are done. This will allow you to control the level of fine tuning of the implementation of the design and UX, as well as skip features when you fear the system might not be ready before your money runs out. 4. If you’re burning your own money, you should have a very very clear vision of how you intend to progress once the MVP is ready. Remember that an MVP is not a finished product, and there’s a limit to how much you can monetize a product at that level of maturity.

How to Serve Cloudinary with HTTPS on Django

Cloudinary’s documentation states that their client side libraries can automatically detect the protocol used in a page and generate HTTP/S urls for the image tags accordingly. This, of course, doesn’t apply to server side code, for which there’s no apt documentation on this matter.

In Cloudinary’s Django library, there are three ways in which you can define your site specific parameters:

  • A dictionary called CLOUDINARY that you can set in your settings.py.
  • The CLOUDINARY_CLOUD_NAME environment variable.
  • The CLOUDINARY_URL environment variable.

Although not mentioned in the documentation, the CLOUDINARY_URL environment variable can take query paramters, and these would be added to the cloudinary object that generates the urls within the Django templates. So to make sure that all requests to Cloudinary are made with HTTPS, all you have to do is set the CLOUDINARY_URL variable with the query parameter ‘secure’ and the value ‘True’, like so:

export CLOUDINARY_URL=cloudinary://123456789012345:abcdefghijklmnop-qrstuvwxyz@abcdefgh?secure=True

Just make sure to replace the fake API key, API secret and cloud name I typed above with your own.

This approach is not so great, though. It forces us to make sure we include the extra query param if we’ll ever need to change the Cloudinary URL in the future, and because it’s not in the code, we can only have all our pages transferred securely or none at all.

An alternative would be to use the CLOUDINARY dict that we can set under settings.py, but that method has a disadvantage as well – it doesn’t play nicely with the other environment variables. In fact, Cloudinary’s Django library regards the three approaches specified above for entering site preferences as exclusionary, so if we set the CLOUDINARY dict under settings.py, the CLOUDINARY_URL will not even be looked at. Considering the fact that under platforms such as Heroku, an environment variable is the preferable route, we’re basically left with nothing but bad choices.

Luckily, the cloudinary object used to generate image links is just python code, the intantiation method of which takes keyword arguments that would be added to the same dict used for storing the site specific values from the inputs mentioned above. So to set Cloudinary to use secure URLs, all that’s required are the following two lines in your settings.py:


import cloudinary
cloudinary.config(secure=True)

That’s it! Your Cloudinary URLs will now always be loaded with HTTPS. Because this is just python code, you can alter it to use secure or unsecure URLs according to different views (just make sure to do that inside view functions and not in settings.py).

Startups Are Bad For You

Socialization of risk

Established companies no longer outsource just the development of new products. Now, they outsource the ideation and planning stages as well. Out of a few hundred teams working from basements throughout the world at any given moment, only a few would reach good results. An established company can choose to only acquire these few, and save up on the costs of trying to innovate internally.

To the economy at large, this isn’t good at all. Established companies no longer spend enough resources on advancing innovation, because they can mitigate the risks of failure by transferring these risks to individuals. Most of these individuals lose. And so, on top of the loss in potential innovation, an important portion of the workforce is busy at work building things that would amount to nothing instead of doing productive work that produces real goods that people can use.

Seizure of public funds

In the U.S a lot of the money in hands of VCs come from people’s pension funds. In Israel, where I live, a large portion of the VC industry is funded by the government. In both cases the money is poured into two main venues – wages for highly skilled workers, and fees paid to a few platform owners – Google’s Adwords, Amazon’s Web Services, Apple’s App Store, etc. In all of these cases, money is being poured from the regular economy with its normal wages to the high tech economy with its disproportionate wages.

A built-in lack of innovation

The startups favored by VCs are those for which there’s already a precedent and a clear business model, i.e not the really innovative ideas, but small improvements to existing tools and services.


There’s an alternative to the startup approach:

  • Just build the things you think are most likely to be helpful to other people.
  • Build tools in the evenings and on weekends and holidays, and whenever you can.
  • Keep in mind that anything for which there’s a clear business model and monetization strategy has already been built. Instead, build things people would find helpful, no matter what the profitability of it might be, and no matter if it can scale.
  • Build for your own sake, instead of working for the sake of potential future income.

Selenium for Python Wrapper Code

First off, here’s the code:


@classmethod
def find(cls, query, selector='id', catch_all=False):
  if catch_all:
    finder = 'find_elements_by_'
  else:
    finder = 'find_element_by_'

  for i in xrange(30):
    try:
      elements = getattr(
        cls.driver,
        finder + selector
      )(query)
      break
    except StaleElementReferenceException:
      print 'attempting to recover \
      from StaleElementReferenceException ...'
      time.sleep(1)

  if elements:
    return elements
  else:
    raise Exception(
      'Could not solve stale reference'
    )

This code achieves several goals. First off, it can PEP8 the code a little by reducing a function call that looks something like the following:

self.driver.find_element_by_css_selector('.some-class')

into the following:

self.find('.some-class', 'css-selector')

Also, by wrapping all the different calls to Selenium’s find_element functions, we can add pieces of functionality that solve some of the inherent problems in the different browser implementations. The code we saw covers stale reference exceptions, that are very common when testing in IE. It would explicitly wait for 30 seconds, trying repeatedly to fetch the element, and breaks out of the loop only when the element is caught. A possible if type(cls.driver) == type(webdriver.Ie) could be added so that this logic would only apply to explorer tests, but this isn’t really necessary, and wouldn’t really work if the tests were migrated to Sauce, for example (where the browser type is always Remote).

Asimilar route could be followed to try and solve invisible element problems. Those occur very often in PhantomJS, due to the browser’s speed, at which some JS driven elements might not be visible on time. The solution to such a problem could be something like the following:


for i in xrange(30):
  try:
    elements = getattr(
      cls.driver,
      finder + selector
    )(query)
    break
  except StaleElementReferenceException:
    print 'caught StaleElementReferenceException'
    time.sleep(1)
  except ElementNotVisibleException:
    print 'caught ElementNotVisibleException'
    time.sleep(1)

I’ve also seen this happen on all browsers when the mouse hovers over elements that expand, thus hiding other elements while Selenium is trying to reach them. A solution to this sort of problem would be to gradually move the mouse until the popped up element is left, and the concealed elements are visible again. Here’s the sample code to illustrate this:


for i in xrange(30):
  try:
    elements = getattr(
      cls.driver,
      finder + selector
    )(query)
    break
  except StaleElementReferenceException:
    print 'caught StaleElementReferenceException'
    time.sleep(1)
  except ElementNotVisibleException:
    print 'caught ElementNotVisibleException'
    action_chain = webdriver.ActionChains(
      self.driver
    )
    action_chain.move_by_offset(50, 50).perform()
    time.sleep(1)

I hope this minor contribution to the code pool that is the blogosphere would make someone’s life a little bit easier some day.
‘Till then, be safe, and Godspeed.

Magento’s Custom Variables Anywhere

Magento’s wiki states that: “CMS content cannot simply be translated in the same way as catalog content. Duplicate pages, blocks, banners and polls must be created for each language.”

The problem is that separate CMS pages would have different URL keys. This creates several complications:

1. Having separate pages with the same content isn’t advised. It’s not so much the false belief that Google frowns upon websites that contain duplicate content (it’s only dissallowed at a disproportional scale that would indicate this is used as a grey-hat SEO trick). It’s more a matter of directing more users to the same pages so as to promote their relevance in Google’s eyes.

2. Locale-dependant url codes make it hard to link to them in other places in the store. For example, a footer link to such a url means you’ll need a locale-based footer block too.

3. If the only difference between store views are those CMS pages, then what’s the point of having to create a separate sitemap.xml file for each locale?

To address these issues in my own store, I hacked Magento’s core to handle custom variables everywhere, and not just through its WYSIWYG editor. The code below is an unintrucive version that uses Magento’s event observers to react to a page rendering and scan for Magento’s custom variables syntax.

For those of you not interested in the tenchnical details, I created a packaged extension that supplies this functionality. It’s available to download for free on my professional website.

For those interested in the technicalities, you’ll notice below that I hook into the response object instead of parsing the individual blocks’ toHtml() methods. It seems surprising because individual blocks are cached in Magento CE, whereas whole pages are not, and it would have saved some parsing time if I were to hook into a method that only runs when there’s no cache available. The thing is, I tested it using Magento’s profiler and it simply doesn’t work as expected. If anyone has any insights as to why, I’d really appreciate a comment.

Either way, to get this working on your own store, create the XML file for the extension here:

ROOT/app/etc/modules/Namespace_Module.xml


<?xml version="1.0"?>
<config>
  <modules>
    <Namespace_Module>
      <active>true</active>
      <codePool>local</codePool>
    </Namespace_Module>
  </modules>
</config> 

Then create the XML file for your extension’s configurations, in which we’ll register our event observer, here:

ROOT/app/code/local/Namespace/Module/etc/config.xml


<?xml version="1.0"?>
<config>
  <modules>
    <Namespace_Module>
      <version>0.1.0</version>
    </Namespace_Module>
  </modules> 
  <global>
    <helpers>
      <variables>
        <class>Namespace_Module_Helper</class>
      </variables>
    </helpers>
    <events>
      <controller_front_send_response_before>
        <observers>
          <namespace_module>
            <type>singleton</type>
            <class>
              Namespace_Module_Helper_Observer
            </class>
            <method>parseCustomVars</method>
          </namespace_module>
        </observers>
      </controller_front_send_response_before>  
    </events>
  </global>
</config>

Last but not least, create the actual observer function inside the helper class, here:

ROOT/app/code/local/Namespace/Module/Helper/Observer.php


<?php
class Namespace_Module_Helper_Observer extends Mage_Core_Helper_Abstract
{
  public function parseCustomVars($observer)
  {
    $response = $observer->getEvent()->getFront()->getResponse();
    $html = $response->getBody();

    $callback = function($matches) {
      $var = Mage::getModel('core/variable');
      $var->setStoreId(Mage::app()->getStore()->getId());
      return $var->loadByCode($matches[1])->getValue('html');
    };

    if (!$this->isAdmin()) {
      $html = preg_replace_callback(
        "/{{customVar code=(.*)}}/U",
        $callback,
        $html
      );
    }
    $response->setBody($html);
    Mage::app()->setResponse($response);

    return $this;
  }

  public function isAdmin()
  {
    if(Mage::app()->getStore()->isAdmin())
    {
      return true;
    }

    if(Mage::getDesign()->getArea() == 'adminhtml')
    {
      return true;
    }

    return false;
  }
}

The isAdmin() function is copied from somewhere. I don’t remember where but I thank it’s author for the code.

This is pretty much it. With this code in place, you can type in {{customVar code=anything}} anywhere in the administration area – configuration menus, CMS page titles, category names, etc, and it’ll parse that into the corresponding value on the frontend.

Hope this helps someone. Please share and don’t forget to test this before deploying as it was only tested on the Magento CE ver. 1.7.0.0.

| Magento’s architecture requires the use of separate CMS pages, with separate URL keys for each language. In this post, I suggest a hack that enables using custom variables in the CMS’s title and content fields instead. Custom variables are translatable, and I’ve been successful at using them as a way of creating language-independent CMS pages.

Chrome is Omnimemoria

I’m in the midst of building myself a Magento website these days, and I ran into a peculiar situation. I was filling out a form in the admin panel of my local Magento installation on Chrome, when it suddenly gave me a drop-down menu with suggested items. The thing is, these suggestions were stuff I typed into a different Magento website I built more than a year ago, and on a different PC. The fact that it remembers data for so long and transfers it from one PC I use to another, can be seen as a feature… I understand that. What I can’t regard a feature is that it’s a different installation of Magento using a different URL, but it still remembered the values I typed into the same fields in the admin panel. This is far more than just an annoyance. Both admin panels are password protected and Magento admin panels sometimes hold credit card information (though it’s not a best practice). It’s crucial that nobody unauthorized would have access to this data. I repeat that these installations were sitting on different locations with different URLs. Now imagine a company that manages several Magento websites. If a certain employee only has authorization on one of those websites, he can still view values typed into fields on other installations that run from that particular browser, as long as someone is signed in with his Google account.