Occasionally I find myself in the highly fortunate position to be asked to contribute to a scholarly journal without having any professional incentive to do so.  This is exciting because I’m as flattered as anyone when someone else is interested enough in my writing to want to republish it.  It also gives me a chance to come into contact with the kinds of contracts that academic publishers offer their contributors.  To put it mildly, these contracts are insane.  In exchange for an unpaid contribution, the contracts expect the authors to give the publishers all sorts of exclusive rights and to indemnify the authors against any sort of infringement lawsuit.

Fortunately for me, and unlike so many people who are confronted with these types of contracts, I have no professional incentive to publish in academic journals.  That makes me free to push back against the contract terms.  The worst thing that happens is that the publisher decides I’m more trouble than I’m worth - it isn’t going to knock me off tenure track or anything.

As what I hope is a service to others who are confronted with these contracts without the ability to walk away, I wanted to publish the version of the contract that the publisher (Kluwer in this case) agreed to pretty easily.  I obviously can’t guarantee that they would make the same concessions again (although it really didn’t take much to get to this point). At a minimum, it might give you the ability to push back when you hear that these terms “cannot be changed.”

All of the struck terms were in the original but are not in the signed contract.  I XXXX’d out the terms of the work because it isn’t really my place to announce the work in advance.  


The undersigned (hereafter called the Author) and Kluwer Law International, XXXXXXX, The Netherlands, (hereinafter called the Publisher)

whereas the Publisher wishes to publish the Work entitled “XXXX ” under the editorship of YYYYYYYYY (hereinafter called the Editor)

whereas the Author has declared his willingness to write the contribution provisionally entitled       (hereinafter called the Contribution) declare that they have agreed as follows: 

1.   The Author agrees to write the above mentioned contribution as agreed with the Editor and/or the Publisher.

2.   The Author hereby grants to the Publisher the exclusive right to publish, sell, give access to and license the use of the Contribution named above in all countries and all languages, in whole or in part, including any translation, abridgement, substantial part, modification or revision thereof, in book form, in a database on its own or with other works and in any form, including, without limitation, mechanical, aural, electronic and visual reproduction and publication, electronic storage and retrieval systems, including delivery of or giving access to the Work by electronic networks, and all other forms of electronic or electro-magnetic publication now known or hereinafter invented, throughout the world, for the full period of the respective intellectual property rights (including copyright) and all renewals and extensions thereof.  The Author hereby authorises and mandates the Publisher to register (at the Publisher’s cost) this licence in any applicable register for intellectual property rights and to take any action and instigate proceedings against infringement of copyright or other intellectual property rights in the Contribution and to use the Author’s name as a party after informing the Author. The Author is hereby licensed by the Publisher to the rights reserved as specified at the end of this agreement.

3.   The Author warrants and represents that to the best of his knowledge the Contribution does not infringe upon any copyright or other right(s), and that it does not contain infringing, libellous, obscene or other unlawful matter, that he is the sole and exclusive owner of the rights herein conveyed to the Publisher, and that he has obtained the necessary permission from the copyright owner or his legal representative whenever a passage from copyrighted material is quoted or a table or illustration from such material is used. The Author will indemnify the Publisher for, and hold the Publisher harmless from, any loss, expense or damage occasioned by any claim or suit by a third party for copyright infringement or arising out of any breach of the foregoing warranties as a result of publication of the Contribution. The Contribution shall be delivered to the Publisher free of copyright charges.

4.   The Author warrants and represents that the Contribution to the Work has not been previously published elsewhere, or that if it has been published in whole or in part, any permission necessary to publish it in the Work has been obtained and provided to the Publisher together with a statement of the original copyright notice.

5.   The Author agrees to be named as author of his Contribution. The Author declares and warrants that any person named as co-author of the Contribution is aware of that fact and has agreed to being so named. The Author signs this agreement also on behalf of and in the name of each co-author, who hereby agree with this agreement in full, in particular Clause 3 and 8. The Author warrants and represents that he is empowered by any co-author to represent this co-author in signing this agreement in their name.

6.   The Author shall receive for the rights granted in Art. 2 a free copy of the (updated) Work plus an electronic file of his (updated) contribution. The Author warrants and represents that any personal use of the contribution by the Author will be limited to the use permitted by the rights reserved to the Author as specified at the end of this agreement. The Publisher shall clearly state the name of the Author in the Work.

7.   The present agreement also applies to future updates to the Contribution by the Author. The Author agrees that the Publisher may request to have a third party take over the writing and updating of the Contribution.  The Author will comply with said request and will cooperate with the new contributor for transfer of his responsibilities with respect to the Contribution. The Author agrees that if the revision has not substantially been prepared by the Author, the Publisher is not required to mention the name of the Author in or in relation to the Work. With respect to such revision the Author waives his moral rights to the extent allowed by law. 

8.   The present agreement can be terminated by the Publisher without prior notice if the Author fails to deliver the Contribution according to the agreed deadline. Termination shall not affect the rights and obligations accrued prior to termination. Any provisions of this agreement which by their nature extend beyond termination shall survive such termination.

9.   This agreement is governed by Dutch law. Any dispute that may arise shall be brought before the applicable court in Amsterdam in The Netherlands.

/s/ 

RIGHTS RESERVED TO THE AUTHOR

 

The Publisher confirms that the following rights are reserved to the Author:

 

•    The right to make copies and distribute copies (including via e-mail) of the Contribution for own personal use, including for own classroom teaching use and to research colleagues, for personal use by such colleagues, and the right to present the Contribution at meetings or conferences and to distribute copies of the Contribution to the delegates attending the meeting.

•    The right to post the full Contribution on the Author’s personal or institutional web site or server, at any time, provided the site has protected/restricted access and acknowledgement is given to the original source of publication; the right to post the full Contribution on any web site provided 3 months have passed since the Contribution was originally published.

•    For the Author’s employer, if the Contribution is a ‘work for hire’, made within the scope of the Author’s employment, the right to use all or part of the Contribution for other intra-company use (e.g. training), including by posting the Contribution on secure, internal corporate intranets.

•    The right to use the Contribution for his/her further career by including the Contribution in other publications such as a personal dissertation and/ or a collection of own articles provided acknowledgement is given to the original source of publication.

 

 

The Author’s rights to reproduce and distribute the Contribution are subject to ensuring that the publication by the Publisher is properly credited[1] and that no commercial use of the publication is involved[2].

The rights reserved to the Author (as stated above) are automatically granted upon acceptance of the contribution for publication and upon signature of this agreement by the Author. Any other rights or personal use not expressly stated in this document are not excluded but may be subject to time limitations or payment of fees. In such cases, the Author has to contact Kluwer Law International to obtain formal permission[3].

[1] “Reprinted from (name of publication), (volume no.), (issue number), (date of publication), (page range), with permission of Kluwer Law International.”

[2] Commercial Purposes includes the use or posting of articles for commercial gain including the posting by companies or their employee-authored works for use by customers; commercial exploitation such as directly associating advertising with such postings; the charging of fees for document delivery or access; or the systematic distribution to other people (other than known colleagues), whether for a fee or for free.

[3] For information on permission guidelines and requests please visit our website: www.kluwerlaw.com.

After waddling my way through some python learning courses, I finally stumbled into an excellent “next step” programming challenge.  It had the ideal combination of a connection to my real life, super straightforward goals, and a handful of moving parts that I was pretty sure I could figure out (but that I would, in fact, have to figure out).  The project was to download an image of the front page of every People’s Daily back to 1993.  This post is going to walk through the process of how to build the python script in a way that I wish someone had done when I was trying to figure this out.  That means instead of code snippets inside of a longer unified program (or just snippets) it will have a series of discrete programs that build upon themselves.  For me, that makes it easier to figure out how each part works.

The “why” I did this is not particularly important, but the “how” is.  The excellent news is that these images are all stored on a server in a standard way.  For example, the image for the cover on April 26, 2016 lives here:

http://58.68.146.102/pic/101p/2000/04/2000040101.jpg

after the /101p/ the pattern is simple: year/month/YearMonthDayPage.jpg

That means I didn’t have to mess with creating a BeautifulSoup object or any real web scraper.  All I needed to do was to create a script that would download the file, move on to the next day, and download that file.  

While that is simple from a programming standpoint, it still requires actual steps that you actually need to code.  The rest of this post walks through each step with a script you can download and break however you want.  All of the code, which is hosted at this github repository is licensed under a CC0 license (more on why I decided to do that at the end).

Step 1: Download & save a picture

The first thing I decided I needed to figure out was how to have python download a picture and save it.   While I started with the template from the excellent Automate the Easy Stuff chapter on web scraping (specifically the exercise that shows you how to download XKCD strips), I quickly realized that it was overkill.  I didn’t need to download and parse a page to find the URL - I already had it.  After a few dead ends using requests, I ended up using the urllib library. The syntax was fairly easy: call it and then pass it the URL you are downloading from and the name you want to save it as.  Here is a fully functioning script using urllib:

import urllib


urllib.urlretrieve(‘http://58.68.146.102/pic/101p/2000/04/2000040101.jpg’, 'test.jpg’)

The first line imports the urllib library.  The second line calls the urlretrieve function from urllib, tells it to download the file at http://58.68.146.102/pic/101p/2000/04/2000040101.jpg and save it to a file called test.jpg.  Note that this will save the file in the same directory as the python script.  You can call the output file whatever you want.

Step 2: Count and Correct Numbers

Next, I needed to remind myself/confirm that I understood how to add 1 to a variable a certain number of times.  That’s a fairly straightforward concept.

I also needed to figure out how to make sure the numbers the represented the date in the program would work when applied to the URL.  The target URL always uses two-digit dates. That means that April is not represented as “4″ but rather as “04″.  In order to be able to find the right file I had to figure out how to turn any integer into a string with two characters no matter what.

Here’s the script that does both of those things:

day = 5

for i in range(0, 15):
     print day
     day_fixed = str(day).zfill(2)
     print day_fixed
     day += 1
     print “I’ve added 1”

The first line sets day to a starting integer.  Note that this is an actual number, not a string.

The rest of the script is a loop that will run a set number of times.  To pick the number of times it will run, change the second argument passed to range (currently that is the 15) to whatever number you want.

All of the “print” commands are just for debugging.  The real action is in the two other lines.

day_fixed is where I hold the version of the day that is turned into a two character string (this becomes important later).  “str(day)” turns the integer day into a string.  .zfill(2) forces that string to be two characters, and will add a 0 to the front if need be.

day += 1 just takes day and adds 1 to it.  That way the days advance every time the loop runs.

Step 3: Iterate

The next step was to combine the ability to advance the dates with the ability to download the file.  I knew  that I would eventually have to make all of the date variables advance (day, month, and year), but I decided to make sure I could do just one before tackling all of them.  Because of that, the script uses strings for the year, month, and page parts of the URL.  That lets it focus on changing just the day:

import urllib

core = “http://58.68.146.102/pic/101p/”

#these all have to be numbers not strings - need to change them

year = “2000”
month = “04”
day = 2
page = “02”

for i in range(0,6):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     urllib.urlretrieve(core+year+“/”+month+”/“+year+month+day_fixed+page+”.jpg", year+“-”+month+“-”+day_fixed+“-”+page+“.jpg”)

Again, the first line imports the urllib that is used to actually download the image file.

The “core” variable is the part of the URL that says constant.  I didn’t have to make it a variable, but since the target URL is a bit complicated turning it into a variable make it a little bit easer to work.

After the note to myself that I’ll need to change the strings to numbers, there is the list of variables that represent the date.  Then there is  a loop that is identical to the last script without the print lines for troubleshooting (it works….).

The last line is the command to download the file.  It is a single line, although it might wrap in your browser.  The first part just calls the urllib.urlretrieve() function.  This function will download whatever URL is in the ().

Inside the () is the URL broken up into pieces.  These need to be broken up because while the relative position of each variable is the same - the path will always end with the month followed by the day followed by the page - the actual value of the variables will change as the script works its way through the process.  That’s kind of the point.  For elements that do not have a variable, I just used strings surrounded by ““.

Each time the loop runs the day is advanced 1, the two character version of the day is created, and then the file at a URL that includes that new day is downloaded and assigned a file name that is also based on the date. 

While the first argument passed to the urllib function has to be what it is, you could change the second function to whatever you want.  I decided to name each file year-month-day-page.jpg.

Step 4: Multiple Variables

Thenext step is to expand the script so it iterates through all of the variables (date, month, and year) not  just date.  Of course, it has to do this in a systematic way so that every combination that corresponds to a date is actually downloaded.  In order to do that, I nested loops within loops.  I wasn’t sure it would work, so I started with just two variables (day and month) to see what would happen:

import urllib

core = “http://58.68.146.102/pic/101p/”

#these all have to be numbers not strings - need to change them

year = “2000”
month = 4
day = 2
page = “01”

for i in range(0,6):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     for i in range(0,4):
         month += 1
         month_fixed = str(month).zfill(2)

         urllib.urlretrieve(core+year+“/”+month_fixed+“/”+year+month_fixed+day_fixed+page+“.jpg”, year+“-”+month_fixed+“-”+day_fixed+“-”+page+“.jpg”)

     month = 4

This is just the previous script with an additional for loop related to the month.  There are two important things that need to be done in order for this to work correctly.  First, the urllib function must be inside the deepest loop.  The most nested loop runs all the way through before jumping up a level, so if urllib is bumped out a few levels you will miss a lot of the files.

Second, you need to reset the variable when its loop is done.  The month loop starts at 4 (because that’s what I set it at in the start of the script) and works its way through 4 times until month is 8 (I limited the number of iterations for testing).  Once it hits 8, the loop exits, the day variable is moved one day forward, and the month loop starts over again.

However, if that is all you do, the month loop will start where it left off last time - at 8 instead of at 4.  This can create a problem if you want it to run, say 31 times for every month.  By the second month you will be trying to download files for the 42nd day of February.

In order to avoid that, I reset the month variable to the original variable outside of the month loop.  Now every time it runs it starts from the same place.

Step 5: Bringing it All Together

Now that I have figured out how all of the pieces worked, I was ready for the final version:

import urllib

core = “http://58.68.146.102/pic/101p/”

#start all of these one below where you want to start because step 1 is +=1

#DON’T FORGET IF YOU CHANGE A VALUE HERE TO ALSO CHANGE IT AT THE END OF THE FOR
year = 2002
month = 0
day = 0
page = “01”

for i in range(0,31):
     day += 1
     #turns day into a string
     day_fixed = str(day).zfill(2)

     for i in range(0,12):
         month += 1
         month_fixed = str(month).zfill(2)

         for i in range(0,6):

             year += 1
             year_fixed = str(year)

             #this needs to go at the bottom of the nest
             urllib.urlretrieve(core+year_fixed+“/”+month_fixed+“/”+year_fixed+month_fixed+day_fixed+page+“.jpg”, year_fixed+“-”+month_fixed+“-”+day_fixed+“-”+page+“.jpg”)

             year = 2002

         #this resets the month to the starting point so it stays in the right range
         month = 0

This uses year, month, and day as variables.  Note that it doesn’t work through the pages.  That variable is necessary for the download URL, but for this first version I didn’t need every page of the paper.  As the all caps comment suggests, you need to set all of the variables one less than the starting variable since the first thing that happens is that 1 is added to them.  You can also manipulate how many years of covers you get by changing the second argument in the year range() function (currently it is set at 6).

Improvements

This script works, which is exciting.  However, there are a few things I might improve going forward:

  • Be smart about dates.  Right now it downloads 31 days of covers for every month.  Obviously that means that some of the files are junk because there is no Feb 31st.  The way to fix this would be to add an if statement to the day loop that changes the number of iterations based on the value of month.  Since I didn’t really mind having a few garbage files I didn’t worry too much about this.
  • Reorder the nesting.  Right now the script will download the January 1 cover for each year, then move on to the January 2 cover for each year, and so on.  This is fine, but if the download is interrupted for some reason it makes it a bit harder to  understand where to restart and it makes it a bit harder to get a sense of how far into the process you are by looking at what has been downloaded.  By reordering the nesting, I could make it download the covers in chronological order.
  • Handle interruptions.  The first two fixes are fairly easy, but this one would require actual additional research. I was testing on this on a few wonky wifi connections, and sometimes I would lose the connection in the middle.  This would cause the script to crash and stop.  It would be great to learn how urllib.urlretrieve handles these sorts of problems, and make the script robust enough to recover.  It can take a few minutes for the script to run, and it was a shame when I cam back only to see that it had crashed three minutes in.

The License

Why a CC0 license?  First, these scripts are so simple that one could probably argue that they are devoid of copyrightable content (except for the comments).  But second, and more importantly, to the extent they are useful to anyone they will be useful for hacking around with trying to learn python.  Even an MIT license would require people to keep a license intact, which seemed too burdensome for this purpose.  CC0 clarifies - to the extent that anyone is worrying about it - that you can do whatever you want with these scripts without worrying about copyright.

That’s the show. Hopefully this is helpful to someone else trying to teach themselves how to do this.

This post originally appeared on the Shapeways blog.

Spring is in the air, and that means that it is time for a few policy updates here at Shapeways.  This blog post serves as a summary of those changes.  As a reminder, if you want to go deeper you can always check out the archived versions of specific policies in order to compare them to the current one.

The biggest update is to the Shop Terms and Conditions.  These terms were last updated in 2012 and, as you can imagine, Shapeways has evolved significantly since then.  In addition to the Shop Terms update, this update includes much smaller fixes to the general Terms and Conditions, the API Terms and Conditions, and the Content Policy.  We are also bringing our content policy precheck program out of beta.  I’ll detail all of the changes below.

Shop Terms and Conditions

These are the terms that govern shop owners on Shapeways.  This update overhauls the format so that it makes a bit more sense, and updates some of the policies.  It also takes steps to simplify the terms.  Since you need to have a regular Shapeways account in order to open a shop, it tries to incorporate terms from the standard Shapeways Terms and Conditions by reference instead of repeating them again in the Shop terms.

For example, instead of having a big section on content rules, the new terms incorporate the existing Content Policy.  That should reduce confusion by just having one content policy that governs the entire site and make the terms a bit more concise and easier to read.

While the payment terms remain largely the same (we pay your markup if it is over $30 on the 15th of each month) there are a few additions designed to clarify policies and address issues that have emerged over the years.

One of the most important changes is to highlight the importance of providing us with correct PayPayl information for an account that can receive transfers from the United States or the Netherlands.  Failure to do this can cause all sorts of problems, so we wanted to make sure that there was ample warning in the terms that you need to do that in order to receive  your markup.

Another change is adding rules about how we handle markups on orders that later get returned or rejected.  Sometimes a model is returned because we did not print it correctly.  In those cases we will continue to reprint the models at our expense and send shop owners their markup.  However, sometimes a model is returned or rejected because of an error on the part of the designer.  We are currently exploring the best way to handle those situations.  It is likely that in at least some of those cases we will not pay the designer a markup if the return or rejection stems from errors that they made.

The changes to the terms give us the ability to begin testing rules governing what happens when a product is returned due to designer error.  The process of exploring options will take some time, and we will strive to do it in an open, inclusive way.  Expect to hear more about the process soon.  Until we roll out a more formal tests, designers will at most receive warnings that their model was returned due to what we believe to be their error.  To put it another way, we will not begin withholding markups for returned or rejected models until we have new rules in place.

Most of the rest of the changes are relatively small.  We added a reminder that some tax authorities require us and/or our payment processors to report data on accounts with gross payments over $20,000 and 200 transactions.  We also did a better job of linking the indemnity and product liability sections of the shop owner terms with the general site terms.  At the end we made it explicit that we may change the terms from time to time.

Finally, we linked the confidentiality terms in the shop owner terms to those in our privacy statement.  Hopefully that will give all users of the site a  more uniform set of expectations in terms of privacy on the site.

Terms and Conditions

As I noted at the start of this post, in addition to an overhaul of the shop terms and conditions we also made some updates to other policies on the site.  In addition to fixing some typos in our general terms, the update has two substantive additions.  These are actually clarifications of existing policies that we wanted to make even more clear in the terms.  Remember that these apply to all users, not just shop owners.

The first is what happens when a model violates the content policy. The terms now make it clear that if a model violates our content policy we will refuse to print it and issue you a refund.  If we catch the violation after we print the model, we will not ship you the model and may not issue you a full refund.

We are pairing this with removing the content policy precheck program from beta.  You can email  content-precheck@shapeways.com if you are worried that a model might run into trouble with our content policy.  Even if your model is incomplete – or even just an idea – we will do our best to give you guidance about how our content policy applies to you.

The second update to the general terms a clarification as to what happens when you remove a model from Shapeways.  The terms now make it clear that we may continue to use the model as part of our internal education and testing process. This is largely because we use user models to develop testing benchmarks that need to be consistent over time.  However, you can still always email customer service when you remove a model and request that it also be removed from internal testing.

API Terms and Conditions

The updates to the API Terms and Conditions are relatively modest.  In addition to some minor typos, the terms now make it clear that developers using the API are responsible for all fraud and chargebacks related to their use.  Since the API developer is in the best position to design their application in a way that avoids these sorts of fraudulent charges, it seemed only fair that they are responsible when someone uses the application fraudulently.

Content Policy

Last on the list of updates is the Content Policy.  The biggest change, which I already  mentioned above, is that we are bringing the content policy precheck out of beta.  Besides cleaning up some typos (by the way, feel free to let me know when you see typos in our policies….), the only other change is to make our preferred way of receiving copyright takedown notices more prominent.  Sending emails to content@shapeways.com is the best way to get a takedown request processed efficiently, and now that email address is more obvious on the page.

Thus concludes the spring recitation of the Shapeways policy updates.  As always, if you have any comments, questions or concerns, feel free to put them in the comments below, email them to me at mweinberg@shapeways.com, or tweet at me @MWeinberg2D.

This post originally appeared on the Shapeways blog.

Last week Shapeways participated in the fifth annual 3D/DC conference.  3D/DC is an event held by the nonprofit advocacy organization Public Knowledge (full disclosure: I used to work there) designed to connect 3D printing with policymakers in Washington, DC.

The world of 3D printing has evolved a lot since the first 3D/DC, and the conference has evolved right along with it. The first 3D/DC (video highlights here) was primarily focused on introducing 3D printing to policymakers and introducing policymakers to 3D printing.  Most attendees of 3D/DC in 2011 had barely ever heard of 3D printing, and may never have even seen pictures of 3D printers.  Similarly, the 3D printing community itself was largely unfamiliar with the policy world and had never even thought about trying to set up a meeting with a Member of Congress.

Fast forward to 2016.  Everyone may not have seen 3D printing first hand, but panelists didn’t have to begin every conversation with an explanation of what 3D printing was.  As a result, after a day of private meetings with Members of Congress and their staff, the public day of 3D/DC could focus on the application of 3D printing to important areas of policy.

Public Knowledge’s Courtney Duffy did a fantastic job of bringing new perspectives and areas of focus to the event this year.  The first panel, on 3D printing and STEAM education included Shapeways’ own Lauren Slowik.  Lauren is our point person on connecting the educational and arts community to Shapeways, so she was able to bring an applied perspective to the conversation.  She was joined by two kids who live 3D printing and STEAM education, John (age 11) and Becky (age 15) Button, along with Sophie Georgiou of Morphi and Joseph Williams of Perris Union High School District.

That first panel set the tone for the rest of the day by talking less about 3D printing for 3D printing’s sake, and instead focusing on how 3D printing integrated into issue areas such as the environment, workforce development, social impact, and the arts.  These panels, which brought together diverse perspectives from both inside and outside of government, were possible because 3D printing has expanded well beyond its original group of enthusiasts.  As we here at Shapeways see every day, many of the most exciting applications of 3D printing comes from people who care less about how 3D printing works and more about what 3D printing can do.

While a policy conference in Washington DC would not be complete without policy panels, 3D/DC is not complete without its culminating reception.  Although many more people have heard about 3D printing in 2016 than in 2011, there are still plenty of people who have never experienced it in person.  The reception and demonstration gives policymakers a chance to see 3D printing and talk to the people behind the printers in a less formal atmosphere.

This reception has evolved over the years as well.  As more and more local community groups, libraries, and maker spaces grow up across the country, 3D/DC can draw on a vibrant local 3D printing scene to demonstrate at the reception.  As a bonus, staffers and policymakers who live in the Washington, DC area can walk into 3D/DC and walk out with information on how to join a local hacker space.  Over the long term, a cadre of wonks who have deep first hand experiences with 3D printing will make sure that 3D printing policy coming out of Washington is created with a nuanced understanding of the technology.

You can check out more about this year’s 3D/DC by searching #3DDC2016 on twitter.  I’ll also try to update this post with a link to videos of the panels as soon as they are up.  In the meantime, you can learn more about what Public Knowledge is doing to help advocate for good 3D printing policy here.

Last week Sparkfun ran a piece on their blog called “FaKey Makey” taking a deep dive into what appears to be an unauthorized derivative of the popular MaKey MaKey hardware accessory.  Briefly - and I commend the entire thing to you - it concludes that a product called the MC2 Circuit Beats manufactured by MGA Entertainment is a derivative of the MaKey MaKey that fails to give MaKey MaKey credit as the source of the idea.  

In addition to the really impressive forensics work in the post, the incident serves as a nice opportunity to reflect on the limits of open source hardware licensing.  It may also help highlight why the Open Source Hardware Association is moving towards a certification model and not an approved license model.

But first…

Some quick background may be helpful.  The MaKey MaKey is a clever bit of hardware that lets you use all sorts of physical objects as input for your computer.  If you are itching to turn those bananas in your kitchen into a piano or use the walls of your living room to control a video game character, the MaKey MaKey is a good place to start.  

It is also open source hardware, which means MaKey MaKey makes things like their schematics available under a CC (in this case attribution, share-alike) license.  

For the purposes of this post I’m going to assume that everything in the Sparkfun article is true and that MGA 1) made something that can trace its lineage back to the MaKey MaKey, and 2) failed to give MaKey MaKey attribution for that history.  Keep in mind that either of those could be incorrect.  I’ll do my best to update this post if I become aware of evidence to the contrary.

Moral/Social Issues

The moral and social issues surrounding open source hardware, derivatives, and attribution can be complex, so I’m going to skip over them here.  Instead, I’m going to focus on the legal and licensing aspects of what happened here. Specifically, did MGA - the company that made the derivative product - violate any licenses?

Does the New Board Violate MaKey MaKey’s License?

Spoiler: I don’t think so.  But I’ll go deeper than that.

MaKey MaKey puts out its schematics under a CC license.  It is important to understand what that really means.  A CC license is a copyright license and can only control the use of works that are protected by copyright.  In this case, the schematics are covered by copyright.  However, this does not mean that the MaKey MaKey itself is covered by copyright. In fact, as a functional object, it is not protected by copyright (there are some clever lawyer arguments that one could use to chip away at this simple statement, but in the interest of clarity I’m just going to work under that assumption).  That means that the license on the schematics are irrelevant to the object itself.

What does that mean?  If you copy MaKey MaKey’s schematics without giving MaKey MaKey attribution, you have infringed on their copyright.  However, if you just decide to copy the MaKey MaKey itself, the license they attached to their schematics requiring attribution doesn’t matter.  You have no legal obligation to give MaKey MaKey anything.

Even if MGA copied MaKey MaKey’s schematics, as long as they kept the attribution on the schematics they probably did not have any obligation to give attribution on the product itself.

Is it Bad that MGA Can Copy MaKey MaKey?

I don’t think that it is.  The fact that hardware can be copied is a feature, not a bug, of IP law.  

Unless MaKey MaKey had a patent on its core functionality, the fact that MaKey MaKey is open source hardware doesn’t really have an impact on MGA’s ability to copy it.  While the schematics  may have made it easier, the Sparkfun post suggests that a determined copier probably could have figured out what was going on without them.

On the flip side, I’d be willing to bet that MaKey MaKey’s openness has helped it grow a community and a market.  I also suspect that this benefit outweighs whatever “cost” making it easier for copiers to access schematics imposed on them.

This incident also serves as a reminder that hardware is open by default.  If you’ve even been frustrated with copyright restrictions, this world of open by default can feel liberating and loaded with possibilities.  If you have ever reverse engineered a piece of hardware without asking permission from the manufacturer first, you understand what that openness means.

Finally, remember that openness goes both ways.  The same legal structures that make it hard for MaKey Makey to protect its core functionality with IP makes it hard for MGA to protect whatever improvements they have come up with.  Even if MGA does not release the schematics, it is likely that MaKey MaKey can reverse engineer them and incorporate them into a future version of MaKey MaKey. (note: maybe do not do this without first talking to a lawyer).  To me, that’s an example of how the openness ecosystem in hardware can extend well beyond a core group of open source hardware devotees.  

Would A Different License Change This Analysis?

I don’t believe so. The core challenge remains that you need a work protected by copyright as a “hook” for any restrictive copyright license.  Even a non-commercial restriction on the schematics probably would not stand in MGA’s way.  (side note: would downloading a copy of the schematics in order to make a commercial product based on those schematics - as opposed to commercially selling the schematics themselves - violate a non-commercial CC restriction?  I don’t know but I’d argue against it).

Would an Open Source Hardware Certification Help in this Situation?

Yes and no.  As I hope this post makes clear, one of the reasons that the Open Source Hardware Association is looking towards certification is because copyright-based hardware licenses can leave a lot out.  Those exclusions can come as a surprise to the people who are using the license.

A certification will not directly prevent someone from making an unattributed derivative of a piece of hardware.  Of course, in many cases, neither would a license. The open by default nature of hardware makes that sort of condition very hard to enforce without patents.

However, to the extent that people see a Open Source Hardware Association certification as valuable, it can help distinguish the MaKey Makeys of the world from the MGAs of the world.  People value openness - and value it more every day.  If a product like MaKey MaKey can stand up and say that they truly are open, it can - I hope - help expand their market reach.

For now, it seems like MaKey MaKey and the MGA board can coexist.  That’s a good outcome too.  My real interest in this incident is that it gives another excuse to do concrete thinking about how open source hardware and licensing can really work.