sublime text 3 packages – knowledge share

Rebuilt my laptop and have been reconfiguring and upgrading stuff ever since. I forget how much customization goes into a dev box. These are mostly notes to myself but if they help someone else, cool.

You can get sublime text 3 at http://www.sublimetext.com/3 – it is my text editor of choice. And like wordpress plugins or tendenci add-on modules, it is extensible. Make it do what you want, right?

ST3 packages and installing them is a bit different from sublime text 2 so I thought I would share what I had to do to get things installed.

Go to this link
https://packagecontrol.io/installation
Then copy the code on the left on that page
Open the sublime console by typing CTL+` (that last thing is a “tick” mark – top left on a mac keyboard)
Paste the code you copied into the sublime console and hit enter.
Then restart sublime text 3.

Next hit COMMAND+SHIFT+P and type in “Package Control: Install Packages”
You should now see a list of packages to install.

Some common plugins that don’t require much thought to decide on. After that install what you need, but no more, to keep things tidy and fast.

HTML5
Makes HTML look pretty and easier to work with by color coding.

Python Improved
To make this your default Python, open a `.py` Python file.
Select `View -> Syntax -> Open all with current extension as… -> PythonImproved`
and you should be all set.

Color Highlighter
Shows CSS codes in the color that is chosen FFFFF for example.

GitGutter
Shows changes since your last commit by putting small visual cues on the left hand side.

sublime-adding-packages

Screen Shot 2015-08-15 at 2.00.23 PM

markdownlight-sublime-plugin

Search for more packages here: https://packagecontrol.io/  They have some good ones for css and less/sass/etc… I’d look for the ones with the MOST downloads as an indicator of if it is a stable plugin.

boot2docker – simplify working with docker containers on a mac

/Geek Warning – all others flee and hide to avoid boredom./

Boot2Docker is a wrapper that makes working with dockers on a local computer just a bit easier.

That’s the goal. Keep it simple and it works. If we really want to keep it simple we now have kitematic to run docker containers with a GUI.

GUI for Docker Container Development
GUI for Docker Container Development

Plus people in programming mode sometimes get insecure and like to (seriously) debate Vi or Emacs as if those who don’t know it are of a lesser kind. I believe in letting compilers deal with my long select-case/kwargs/collections/dictionaries/whatever you want to call them. Thus I LOVE seeing tools that make programming EASIER. Especially visual ones even though I’m back to preferring the command line.

But back to boot2docker for working with containers locally. On a Mac, it’s nothing most of us haven’t done already with Virtual Box (free) or VMWare (not free but faster than VB) sharing a local folder into the VM. We all do this so we can use our dev tools without even more junk into the VM itself.

Number 1 reason to use it if you use a Mac? It doesn’t make me install homebrew (not a fan – sorry) and mess up the $PATH on my Macs. And Containers are just cleaner than virtualenvs as there are no dependencies, only attached containers. ‘Tis beautiful.

OK, the point of this post – if you are having any problems installing boot2docker on your Mac as I did, first it probably is NOT your fault. OK, well maybe it is because we all like bright shiny things and have a ton of junk installed. For me I would install it and it just would not start up. I found the documentation sort of glazed over a few things. So here you go.

  1. Upgrade to the latest Virtual Box BEFORE installing boot2docker. For me it just hung and didn’t give me a clue what the problem was. Do this first.
  2. Let b2d put its .pem and other keys where it wants to. You don’t need to even put these in your .ssh folder either.
  3. I did put it’s three environment variables in my bash because I’m lazy.
  4. You don’t have to sudo when you call “boot2docker up”. It doesn’t like that.
  5. You don’t have to make an entry in your /etc/hosts file for the dev server. Maybe more convenient but the IP works just as well.
  6. SSH – I made this waaaay 2 complex. it’s like vagrant. Just type “boot2docker up” followed by “boot2docker ssh” and you are in.

boot2docker-self-sufficient-runtime

Again – keep it simple and don’t make life complicated like I did. Install the boot2docker app for mac from the site. Install the package for Mac. Then from terminal:

boot2docker init

You only have to run that once. Then from anywhere:

boot2docker up
boot2docker ssh
exit
boot2docker down

Of course you might want to try out some of the exercises after the “boot2docker ssh” line when you are in the environment. Just trying to keep things simple, but no simpler than needed.

state

State
Impure functions are often more efficient but also require that the programmer “keep track” of the state of several variables. Keeping track of this state becomes increasingly difficult as programs grow in size. By eschewing state programmers are able to conceptually scale out to solve much larger problems. The loss of performance is often negligible compared to the freedom to trust that your functions work as expected on your inputs.

Maintaining state provides efficiency at the cost of surprises. Pure functions produce no surprises and so lighten the mental load of the programmer.

http://toolz.readthedocs.org/en/latest/purity.html

Brackets editor – new to me

Brackets editor by Adobe. OK, I assume they purchased it, but it’s under their brand. Link:

http://brackets.io/

After download on the Mac, if on Maverick, it will prevent you from running it. Instead of using Alfred or Spotlight, try instead:

1) Download
2) Install in apps (click the dmg from the step above)
3) Go to apps, find brackets.app, and hold CTL while you click it. This should bring up the option to “Open” as well. Do that.

Screen Shot 2013-11-25 at 2.08.36 AM

Apple’s switch to SMB2 with Maverick and Developing with VMWare and Ubuntu

On Tendenci development configuration…. Through one of the thousands of sources of input that hit me in a given week between websites, newsletters, other programmers, employees and random people I talk to, it finally clicked with me the significance of Apple switching to SMB.

OK, to back up for non-geeks. Computers talk to each other and devices like printers using common protocols. Microsoft, going back to modifications to DOS has used SMB. (skipping a bunch of history here.) Fast forward to a few weeks ago when Apple released OSX Maverick for free. In the release of Maverick everyone talked about how it was FREE. They are giving away the software counting on us to buy the hardware. OK, I get that.

Tendenci Open SourceWhat they also did was change from their own network protocol, called Apple Filing Protocol, and switched to Microsoft’s protocol SMB. Wait, what? Why?

Well, first Apple made their OSX Server software $50 in the app store. A comparable server software package from Microsoft is $2500. So I purchased a Mac Mini server. Sadly with even 35 users it wasn’t that fast. AFP is slower that SMB I’m told. But they could have improved AFP. Instead Apple made the switch to SMB. This not only speeds up their server but most importantly it allows MACs to connect to local area networks managed by Microsoft Servers without any extra software or tech support needed.

Apple is moving into corporate America folks.

Apple owns the home/consumer market in my opinion, even if I have an android phone our house is full of mostly Macs. 1 or 2 PCs or Linux but mostly Macs. Our company is already fully switched to Macs and Linux and the Cloud. But a lot of companies have not. I’ll leave predictions of Apple’s strategy to break into the Fortune 500 to reporters far more qualified than me.

What I do know as a programmer is that my life just got a LOT easier.

/back to geek speak/ We program on Linux but use Mac laptops. So we are always connecting back and forth which is a pain. And developing locally, on an airplane for example, I need virtual linux machines that run on my local computer. For that I used to use open source Virtual Box by Oracle, but it’s too slow on a Mac IMHO. I tried VMWare Fusion 6 and apparently they have a deal with Apple allowing direct access to the hardware. All is know is that VMware is MUCH faster than virtual box or vagrant. And I’m impatient so I’ll pay the $70 ish for VMWare Fusion.

Previously to share folders between my local computer (Mac) as the host computer running a virtual Linux computer on VMWare (Guest) required me to set up sharing through VMWare. This gets complicated. Your host folders are mapped to /mnt/hgfs/ inside of linux. If you symlink into a project and install software, given it is a symlink that means your files will still install in the /mnt/hgfs/ folder. For example:

Project folder path to virtualenv inside of Linux 12.04 LTS might be:
/var/www/projects/mydjangoproject/venv/
Linking from VMware Fusion you would create a share perhaps similar to
/mnt/hgfs/shares/projects/mydjangoproject/venv/
that pointed to your virtual environment folder.

Because this is a sym link, if you install a virtualenv for example the path maintains the linux path. So a “which python” gets you something in the /mnt/hgfs/shares/projects/ folder instead of the /var/www/projects/mydjangoproject/venv/. This makes portability a problem.

Samba to the rescue. The above method required configuration of the virtual machine through VMWare fusion, which slows down designers. And doesn’t easily port to VirtualBox or Vagrant. You can make magic happen by using Samba:
https://help.ubuntu.com/12.04/serverguide/samba-fileserver.html

Installed in the guest OS, for me 12.04 Ubuntu, and setting up your /etc/samba/smb.conf file with something similar to this:

[www]
path = /var/www
browsable =yes
writable = yes
guest ok = yes
read only = no

Restart you VM and magically in Apple’s Finder you will now see the local VM in your “shared” portion of finder.

Lastly for the programmers out there, do a bit more research before using anything other than NAT on your local for security. You have to configure file sharing security on the Mac host. Samba sharing security via smb.conf. And chmod/chown security on the folders and files inside the linux guest. While it might be tempting to just blow down the house with 755, remember that whoever takes that image might bridge the adapter and…. well, that would be your fault. So be careful out there kids.

Still, loving the fact that my directory structures can be identical, that I can pass off a vmware image to a colleague and it JUST WORKS. Dreamweaver edits, bash, git, whatever. Between SSH and the adobe suite you are now all powerful to make better looking applications using better software. Rock. On.

pycrypto install fails on mac osx mountain lion in virtualenv

Receiving the following errors trying to install pycrypto in a virtualenv on mac osx mountain lion. Assuming the name of the virtualenv is “PROJECTVIRTUALENV” and that your project is PROJECT my first try was:

[powershell]
$ mkvirtualenv PROJECTVIRTUALENV
……… change into the project folder
$ pip install -r requirements.txt
……… everything installs except pycrypto
$ sudo pip install pycrypto
[/powershell]

that also fails resulting in:

[powershell]
File "/Users/eschipul/.virtualenv/PROJECTVIRTUALENV/build/pycrypto/setup.py", line 278, in run
raise RuntimeError("autoconf error")
RuntimeError: autoconf error

[/powershell]

This was a new one on me so what changed? A few things. First virtualenv and virtualenv wrapper now default the –no-site-packages, but you were using that already.

Second the upgrade from OSx Lion to OSx Mountain Lion required an update of the command line tools with xCode. I’ve tried the stand alone xCode tools and they don’t keep up with Macs updates so I have the whole bloody xCode installed on my machine. To resolve the install problem with pycrypto it needed the new compiler. Simply updating to xCode 4.4 does not solve the problem by itself.

Per a note half way down this blog post on similar installation troubles by jiaaro you need to re-download the command line tools. From the post:

You need to install Xcode 4.4 (from the app store) and then, within xcode open Xcode > Preferences (or press Cmd +,) then open the downloads tab and install the Command Line Tools.

which looks like this:

and results in this:

[powershell]
sudo pip install pycrypto
password:
…. yada yada yada …. a warning or two …. then
Successfully installed pycrypto
Cleaning up…
[/powershell]

Note that I *did* already have the command line tools installed on xCode 4.3. The upgrade didn’t match my previous config and I had to explicitly download them again. Hope this saves some other poor soul some time as it makes no sense to me. But there it is.

never fathomed the idea that we can use git to send runnable code to the cloud

…we associate git only as a tool for managing source code (some of us only use git in conjunction with github, and have never fathomed the idea that we can use git to send runnable code to the cloud).

So, I was forced to decouple my notion of “git” as a version control tool from “git” as a generic source code commisioning utility, when I decided I wanted to experiement with deploying a blog … I quickly found that I didn’t fully understand heroku’s model.

jayunit100 (source)

Yup. Me neither. Great blog post if you are interested in experimenting with Heroku.

convert legacy django mysql dbs from myisam to innodb

The Problem and the Virtue of Transactions

Disclaimer: a long time programmer, old guy, learning new tricks. If I made a mistake please let me know in the comments and I’ll credit and update the post. Thanks!

Short version: For Django – MYISAM BAD. INNODB GOOD. Fight it if you wish, but for me, this was the bug and the fix. (Oh, and everything below relates to a Mac OS X 10.7.3 so translate to your OS.)

Django supports transactions. This is a good thing. And recommended. In my case I had a bug where something in admin delete worked on my local machine but did NOT work in staging. Tres embarrassant!

Specifically (for the now open source Tendenci software) I was struggling with building a Tendenci Django plugin with related objects (categories, etc) and attached images (files). Basic CRUD stuff. CRUD worked on my django dev environment locally, but only CRU worked and D failed in staging. Specifically Django failed on delete with a relationship error. Can’t delete three things at once. Why? Hmmmm. Stumped.

Thanks to debugging by JMO, he found the difference is our staging and production database servers have tables that are set to INNODB as the storage engine and my local mySQL defaulted database tables to MYISAM (MySQL 5.1). Thus trying to delete an object through the Django admin failed in staging because it could not delete three things at once in INNODB which strictly enforces relationship rules. OK, that seems fair. MYISAM is more willy-nilly-do-whatever. Which means you have scraps of relational data left in your tables. Yuck. Long-term-data-mining-hell.

Bottom line – transactions in Django are not supported at a database level with Django middleware with MYISAM and thus I couldn’t wrap a (multi-)delete into one call in admin.py. Sure we could programmatically delete the objects in sequence as a quick bug fix, Yet I’d rather let Django handle the heavy lifting (and shorter code). And long term there is a strong need for transactions. Especially in the age of RESTFUL APIs (I miss you soap! NOT!) In current web development with API calls dependencies can easily be on 30 routers and 20 servers just so you can post a pic of your chicks to Instagram Flickr. Thus you have to be able to roll back transactions. That is part of what a framework does. And transaction rollbacks clearly should NOT be the application layer’s job IMHO. MVC and all even if C is in V in Django. Another debate…. So transactions it is.

How to upgrade the dev mysql database environment from MYISAM to INNODB?

The fix that worked for me came from this post on converting a mysql database to INNODB for Drupal as well as several others credited below. While this post is on Django, Drupal still supports both MYISAM and INNODB, the default in Drupal 7 is now INNODB. So don’t fight the man. I’m moving to INNODB for Django too.

What steps are required for Django on MYISAM on a Mac OSX to get transactions working in Django? Combining a few of the posts (all linked below) and the django transactions help file you wind up with the following:

First convert your database. To do this create a temp directory and change (cd temp) into it using terminal. Run the commands from this post. I repeated them below slightly changed and I am skipping the prompt indicator to make it easier to copy.

First check if this is even a problem by getting a list of databases that have tables that use MYISAM

mysql -u USERNAME -p
#it will prompt for your password here
SELECT table_schema, table_name FROM INFORMATION_SCHEMA.TABLES WHERE engine = 'myisam';

You will get some results from “information_schema” and “mysql” and I’d recommend not changing those. Just look for your dev databases.

Second create the SQL file to change the offending databases that are your Django mysql databases.

cd temp
mysql -u USERNAME -p -e "SHOW TABLES IN YOURDATABASENAME;" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=INNODB;" > alter_table.sql

It will prompt you for your password and replace the USERNAME and the YOURDATABASENAME with your own. Side note, don’t put a dash in your database name or it won’t work. I want those 30 minutes of my life back. Moving on….

I’m a curious guy so I wanted to see the contents of the sql file. (Replace “Sublime Text 2” with the text editor of your choice. I just use Sublime because Glen told me to).

open -a "Sublime Text 2" alter_table.sql

Ooooh. Aaaaah. Looks fine. OK, close that. From there I prefer to do the update one database at a time to be sure so this:

mysql -u USERNAME -p YOURDATABASENAME < alter_table.sql

Then to confirm run the myisam table query again (which we hope does NOT show our now converted DB.)

SELECT table_schema, table_name FROM INFORMATION_SCHEMA.TABLES WHERE engine = 'myisam';

All good? Cool.

For all I know INNODB might break another database so I am only focusing on your Django mysql databases. Now in your settings.py file in your Django project be sure you have the following line as part of your DATABASES setting.

'OPTIONS': {"init_command": "SET storage_engine=INNODB",}

The whole settings.py mysql connection setup now looks like this because I hate when people leave off the context of where to put code or the details (I’m looking at you StackOverFlow.) /rant/Actually the only thing I hate more are code examples that use sqllite because they are close to useless. /rant/

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'YOURDATABASENAME',
        'USER': 'USERNAME',
        'PASSWORD': 'BLAH',
        'HOST': 'BLAH',
        'PORT': 'BLAH',
        'OPTIONS': {"init_command": "SET storage_engine=INNODB",}
    }
}

Now when you run from your project directory the usual “python manage.py syncdb“ command it doesn’t use the database defaults regardless. Anything new should be automatically created INNODB.

The following posts are the entire basis of the content above. I just combined it all in one place specific to Django and MySQL on Mac OS X. Comments and corrections are welcome.

  1. https://docs.djangoproject.com/en/dev/topics/db/transactions/
  2. http://djangosaur.tumblr.com/post/357759467/django-transaction-mysql-engine-innodb
  3. http://www.electrictoolbox.com/find-innodb-tables-mysql/
  4. http://www.mikebernat.com/blog/MySQL_-_InnoDB_vs_MyISAM
  5. http://highervisibilitywebsites.com/convert-your-mysql-database-myisam-innodb-and-get-ready-drupal-7-same-time
  6. http://stackoverflow.com/questions/9947671/performance-difference-between-innodb-and-myisam-in-mysql
  7. http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB

 

mind as water as programming

There is a natural conflict between youth and programming. Frequently the best programming ideas, like in mathematics or chess, come from young people. Sometimes under 30. And in my experience focus becomes harder as you age. Young people don’t know what they can’t do and this often allows them hit the ball out of the park! A very good thing indeed!

The contradiction is the young guns with the fresh mental horsepower have the least experience and frequently charge around randomly between the latest cool “philosophy” and “tool” making less progress than an older programmer who might quickly determine what to avoid. And youth can sometimes be unwilling to compromise the reality of programming economics (code actually runs on hardware I’m told) and the beauty of full normalization. (Hint: your college prof was wrong. Talk to an experienced dba and she will speak the truth. Normalization is a goal like reaching the axis on an exponential curve.)

Currently I am trying to catch up with my team on Python and Django (they have really left me in the dust at the moment) I enjoyed this quote from DRY:

My biggest programming headaches have always come from abstractly struggling with “how can I write a good general solution to this problem”, even though I only know of one place where it’s definitely going to be used. “I’d better think of a general solution now,” I think, “or I’ll have to copy-and-paste-and-change code!” But it’s absurd to try to come up with a general solution without knowing more about the different varieties of the problem that exist (or will exist) in the system.

It’s a battle of two really strong urges - OnceAndOnlyOnce vs avoiding Premature Generalization. Do I duplicate for now and try to live with the duplication for a while, or violate YagNi and come up with some half-cocked generalized solution? It’s a tough one, because almost all programmers hate duplication; it’s a sort of primordial programming urge.

However, even though CopyAndPasteProgramming can be expensive to clean up, so is a botched “general solution” – and copy and paste is far cheaper up front. So I also am in favour of temporary duplication, to be refactored when you have a clearer view of the situation. – MatthewBennett

In our shop I have always called it “do it once for all time for all users.” But it means the same thing. Repeating yourself and not solving issues at the root level is a waste of time. I can’t tell you how awesome it is to not have to explicitly declare getters and setters in Python (vs classic ASP where classes don’t even have inheritance.).

Yet there is a catch. At the beginning of a project or approaching a new industry you can’t really do “root cause analysis” because you don’t have any data. To requote the quote above –

However, even though CopyAndPasteProgramming can be expensive to clean up, so is a botched “general solution” – and copy and paste is far cheaper up front. So I also am in favour of temporary duplication, to be refactored when you have a clearer view of the situation. – MatthewBennett

– this balance is the solution and yes it is a bit messy. If the goal of programming is to make a profit then you can’t just argue philosophy without discussing the economics of it. Economics as in money. And economics as in sometimes duplicate code or duplication of data just runs faster on the servers, increases your search engine rankings and lowers your operating costs. I can live with a bit of duplication for that reward.

Often the best solution is to collect data and slam it together and then identify the best organizational structure before the corpus gets too large. Programming classes or actual data both. A filing system for terrabytes of photos and videos for example. It is a balance between the default import settings of all of the hardware you use and the need to compartmentalize source and work product for portability and backups. Yes, you have to compromise to the machines somewhat because you can’t change the settings on every other camera in the world.

Let the data build up a bit. Don’t fight the hardware. Live with some duplication. Then generalize and normalize as best you can. Balance. “Mind as Water” as Lee would say.

I Just Need a Website, That’s All I Need

caller: I was calling about a web site

developer: cool, that’s what we do. how can I help?

caller: I have a simple site and I need some updates. not much really, just a few changes. is that something you do?

developer: yes, what is the url?

caller: well I’ll need you to sign an NDA before I give you the url. can I fax it over?

developer: no (thinks: “do I still have a fax to email gateway working? hmmm”)

caller: what?

developer: we just met and you want to fist bump attorneys?

caller: no, i just don’t know how else to protect my intellectual property!

developer: you have a site now, right?

caller: yes

developer: live on the internet?

caller: yes

developer: …… long pause…..

caller: ok, I see your point.

…. 45 minutes of spec requests and contract pre-negotiation convo takes place here….

caller: so basically that’s it. my brother-in-law said he could build it for $225 dollars but I wanted to call around and get a few options to see if I could reduce the cost. He’s not very good actually.

Thoughts going through your head as the dev:

  1. developer (option 1): so you have a job board and you want to enhance a few features of monster.com to allow for a commission and affiliate structure?
  2. developer (option 2): so you have a great e-commerce idea, have been reviewing amazon.com and found a few ways to improve on their theories to sell widgets?
  3. developer (opti0n 3): so you want to have a self sustaining site that makes you money with no effort invested while you work at your current job realizing the money-for-nothing potential advertised on TV?

Resolution: have you heard of Crowdspring?

#respect #withAllDueRespect

iPhone Apps Make 4 to 6k Total?

And THIS is why we don’t make iPhone apps:

With more than 350,000 apps available on Apple’s digital store, game creators are finding it tough to attract attention despite tens of millions of potential customers who own Apple gadgets, he said.
“They have over-encouraged supply,” Hawkins said on a panel at the conference. Using statistics that Apple has made public, Hawkins calculated that each app earns, on average, about $4,000.
“Four thousand per application: Do you see a problem with that?” he asked the audience. “That doesn’t even pay for a really good foosball table.”
Apple said Wednesday it has doled $2 billion out to app developers, which could put the average payout closer to $5,700. Either way, Hawkins said he believes the math makes it difficult for creators of apps to turn a profit.

Incidentally, depending on the complexity of the App you will get quotes from 10k for a “brochure” app all the way up to 250k. Even on the low end you are looking at a loss. This isn’t to deny that Angry Birds won the lotto and hit it big. But think of making iPhone apps more like trying to get into the NFL. You might. But the odds are stacked against you and the competition is fierce.

the rules driving python

  1. Borrow ideas from elsewhere whenever it makes sense.
  2. “Things should be as simple as possible, but no simpler.” (Einstein)
  3. Do one thing well (the ‘UNIX philosophy’). And that was to create a great programming language that can be used anywhere.
  4. Don’t fret too much about performance – plan to optimise later when needed.
  5. Don’t fight the environment and go with the flow.
  6. Don’t try for perfection because ‘good enough’ is often just that.
  7. (Hence) it’s okay to cut corners sometimes, especially if you can do it right later.
  8. The Python implementation should not be tied to a particular platform. It’s okay if some functionality is not always available, but the core should work everywhere.
  9. Don’t bother users with details that the machine can handle.
  10. A large complex system should have multiple levels of extensibility. This maximizes the opportunities for users, sophisticated or not, to help themselves.
  11. Errors should not be fatal. That is, user code should be able to recover from error conditions as long as the virtual machine is still functional. At the same time, errors should not pass silently.
  12. A bug in the user’s Python code should never be allowed to lead to undefined behavior of the Python interpreter; a core dump is never the user’s fault.

LinuxUser, Python, the Universal Programming Language paraphrasing Guido van Rossum

Adding eBook epub and mobi downloads to WordPress

A few technical notes if you want to add ebooks (.epub and .mobi file formats) downloads to your wordpress site. We encountered three obstacles, file size, upload restrictions and file association. Here are the solutions.

WordPress File Size Limits are Too Low

WordPress by default only allows 2 meg uploads and only of particular file types. Unfortunately .epub and .mobi are not among the default file types that are allowed by WordPress.

First the bad news – if you want to increase the allowed file sizes for uploads you have to modify the php.ini file. Depending on your hosting provider this may or may not be easy. See Bill Erickson’s post on increasing allowed file uploads in WordPress.

File Types That can be uploaded in WordPress

Hopefully this will change, but currently .mobi and .epub are obscure. So you have to configure WordPress to allow them on most hosting providers.

We are running the WordPress Thesis theme on this particular site so the solution to add file types for upload was found here and is abbreviated below.

In the Thesis custom_functions.php file add this php code using the WordPress editor. But don’t make a typo as after that you would have to FTP in to fix it. Hypothetically speaking. Here is the function modified from the link above.

function addUploadMimes($mimes) {
    $mimes = array_merge($mimes, array(
        'epub|mobi' => 'application/octet-stream'
    ));
    return $mimes;
}
add_filter('upload_mimes', 'addUploadMimes');

The above example only includes the .epub and .mobi examples, but if you want more just pipe-filetype further where the code says ‘epub|mobi’.

Change the Content-Type for epub Files Served by Apache and WordPress

All fixed, right? Not so fast. WordPress serves unknown files with the content-type of “Content-Type text/plain” in the HTTP header. You can see this using the excellent long-lasting Rex Swain HTTP viewer.

The problem is that while Windows handles the misidentified .epub files fine, Macs freak out and show you the binary. You click it on a Mac and see garbage. Not cool. Must fix.

I found this post in the WebFaction support on adding epub to the .htaccess file to change content-type by file extension. A bit of modification and I found adding this to the application root .htaccess file did the trick

AddType application/epub+zip .epub
AddType application/x-mobipocket-ebook .mobi

A word of caution – BE CAREFUL WITH YOUR HTACCESS file! It probably already exists so be sure to download-backup-modify-upload-via-ssh for maximum security. Or really sFTP is plenty secure as well.

Other epub and mobi pit-falls to look out for

The ePub must be strictly validated. it is really a Zip compressed directory with it’s own MIME type specification. And XML that must be valid. Google “epub validation” if the above list did not solve your problem and go from there.