Follow the changelog on Twitter!
January 28, 2013 Moved all sorts of things around in the morning: javascript into its own files, in hope of cutting page-load times; book-response saving into the cache, so results persist across workers; and everything I could into queues to keep HTML generation speedy. It all seemed to work well enough, and main now loads 0.6 secs faster, which isn't quite fast enough, but hey, I'll take it for now.

In the afternoon, I chased bugs. Pages aren't reloaded when someone's followed or unfollowed; the missing comments, erm, everywhere are back (twas a cache-key issue); and book recommendations carry forward from a book-profile pages. Finally, I added more (queued) emails for myself, in the hope of better understanding how people navigate the site and think about shelving books.
January 27, 2013 After a not-so-brief detour into z-index CSS doom, the drop down lies on top of what it's supposed to (unlike it was doing before) and doesn't curl up needlessly early. I'd noticed this before, but it seemed like it'd prooooobably be tedious to fix. Some poking from one of Laisin's users got me to fix it today, which meant I learned about Jquery's rather-useful data() function. Also spent some time prodding the subscription page into something more clear to people-who-aren't-me. (We're not quite there yet.)
January 25, 2013 Added in actual support for buying a subscription for a non-Laisin user; it didn't quite work properly before. Also spent an egregious amount of time putting together sets of books (it was fun!): Nonfiction selections, Fiction selections, Best biographies, Science and psychology favorites, Economists' explanations, Startup guides, Choices from the sci fi canon, Popular graphic novels, Ageless "kids" books, and Beginner books. (Admittedly they all need waaaaay better names.)
January 24, 2013 Spent more time this morning on the bulk shelver, which was a pretty unintuitive page. It's slightly better now; there's more separation between the different books. In doing that, I caught an irritating bug: the way I'd been saving Google Books API results didn't translate, suuuuuper frustratingly, so I re-worked it to store ISBN numbers. (Storing titles, and querying those later, isn't enough, because you'll still get the wrong book sometimes, since it's an "I'm Feeling Lucky"-style search.) (This is one of those things that I don't think anyone will ever come across, but so it goes.)

I changed the profile pages back to the way they were; it didn't take me long, staring at the new, wider, border-less images, to decide they were terrible. On the plus side, the more-consistent book buttons are here to stay. (Each book on a profile page can be reshelved, commented on, bought, recommended or -- if you're looking at your own profile -- removed; if you're logged out, books can only be bought.)

Most of the evening was spent re-working subscriptions to 1) work as gifts for other people; 2) work across other people's shelves; and 3) add in some pre-set shelves that I'll make of really, really good books. I'd sketched out what I'd wanted the page to look like last week and was pleasantly surprised that implementing it didn't take forever. (Only half of forever this time.) I spent too much time late at night, planning what I'll put on those pre-set shelves. I'm excited for this.
January 23, 2013 I'm on really slow internet this week (family vacation, not in NYC) which led me to spend an hour this morning re-doing caching and more specifically/hopefully, making it all more efficient. I also got tired of how slooooooow the Google Books API is, so I added an easter egg (of sorts) to book shelving for those with slow connections.

I also deployed, but haven't really told anyone about, a bulk shelver that lets you search for and shelve up to ten books at once. (With autocompletes! That each work! And don't mix up themselves!) This, too, was a thrice-requested feature. It still needs cleaned up, visually and usability-wise, but I'm planning to start sticking it in front of new users. (When I design that new-user onboarding process .. ) I also convinced someone else (Zander!) to import their GoodReads books, and it all worked! The first time! (Well, beside some pretty significant copy confusion. But that'll get re-written.) And then, because I'm crazy, I spent too much time muddling in CSS-alignment DOOM to create orange shelves. They're orange, don't really fit the rest of the page's aesthetic ("the rest of the page has an aesthetic?" one asks innocently), and are pretty finicky, but I think some version of them will stick around.
January 22, 2013 Re-wrote parts of importing, so that failed imports aren't as cataclysmic. (Spending an hour cleaning out a database will do that to you, I guess. Should've been done in the first place though.) Convinced Sidd to import his GoodReads books (erm, twice) so I could continue to live-debug the GoodReads importer; his books had new and interesting bugs! Compared to the books that had gone before. (Related: now I really, really, really understand why there's a production version of a site, that runs on all the same infrastructure, for testing.) Also put all email-sending into its own queue, since their timeliness is less important than any sort of page serving and took out some logic that wasn't really being used but was probably slowing things down. It feels like I did more today, but my commit logs aren't very promising.

Unrelated to Laisin except in subject matter: I finished two books this morning! (I've basically stopped reading since I've been working on the site; one of the cruel ironies of all of this.) Peter Hessler's River Town was amazing -- read it!, and Sal Khan's The One World Schoolhouse, which was much better than I'd expected.
January 21, 2013 Installing Redis: not the worst thing ever. Getting my imported books to work with Redis queues? Waaay more irritating. (Apparently you can't send files into Redis queues? You've got to do something sensible, like save them somewhere, and then pull them out later? This all seems pretty silly.) But after a few hours of struggling, and some re-writing, I've got importing working again! With queues! Though the first time I tested it live, with a friend's data, it failed because the queue timed out before the import completed .. and then the same thing happened the second time .. but the third time, with the 30-minute limit on queue timing out -- that's when everything worked out!

Related: a brief lesson on logging, conducted over email, resulted in this picture.

Aaaaalso using Gunicorn, rather than Flask's default server, means I can run the worker process without running a worker dyno, thereby saving me $39/month and nearly making Laisin breakeven for the month!
January 20, 2013 I've got gunicorn, installed and working locally! It actually wasn't too painful to install, which either means I'm getting better at this whole installing-software thing or (more likely) I just chose something well-documented. I played around with the multiple processes a bit and thiiiink I've got them working; I'm hoping to use at least one as a worker, once I figure out how to install Redis, for the heavier tasks like importing books. I worked on importing books too, and added book-removal and reshelving to the post-import screen. (I bet only one person will ever use these, ever. In which case: I built these just for you!) Also poked at the design of main for what feels like the 38482929th time, and started putting blocks underneath the books: one for the person who just shelved the book, one for the comment, and one for the prior reader (person from whom the book was reshelved) or the recommender.
January 18, 2013 More great usability feedback, this time from Nate. Some of the more interesting fixes include: why'd I decide you upload a profile photo with a 'png' extension but not a 'PNG' extension? Who knows; character-length limits were added all over the place on /main (why'd I create such a tiny layout again?); and additional padding on user photos on follower/following pages (you can never have enough padding.) A bunch of iteration on what the screen looks like after you've imported books, when you can edit them. Here's what it looks like for now; you can mark books as read, comment on them, or buy them. You proooobably should be able to remove them from your shelf and re-shelve them, too. I also figured out why no one was clicking on my Amazon links .. I just wasn't recording the clicks properly. D'oh. Tony talked to me a bit about multiple threads and processes in web applications -- something I didn't really know about, beyond buzzword bingo -- which convinced me that I should go look at some of this stuff, in the hope of speeding up Laisin. (It's gotten very slow again. Why? Who knows.) Ah and -- by the end of the evening, I'd decided that I & lt;3 HTML encoding.
January 17, 2013 Hi new users! I spent most of the morning building an importer for GoodReads books, and then, in my zeal to test it, I hit the Google Books API limit. One API code swap later, and I was back in business. In the evening, I got a little distracted by the new users and built myself a slightly better (but still pretty shoddy) stats page. A few things I learned: 1) Laisin's top books are Gödel, Escher, Bach (a book that I'll forever be associated with character-encoding issues, thanks to Laisin); Country Driving, The Signal and the Noise, Thinking Fast and Slow, and Snow Crash. (Guess the demographic of my user base?); and 2) 14.7% of users have recommended a book to someone else. I (Christina) made 61% of those recommendations. Recommendations must be pretty hidden, and perhaps should be melded into shelving.
January 16, 2013 Bug fixes first: when a book has no authors, nothing dies (thanks, Harold!) and changed the reshelving notification on main to appear at the page top, rather than on the book cover, because everyone was missing the notification when it appeared on the book's cover. The comment-entry box is now below the discussion, after four people (!) thought it looked funny that way. (I sorta thought I could get away with it because that's what Instagram does, but no, Laisin is not Instagram. Surprisingly enough.) The full comment appears on hover on /main too, in an admittedly-slow-but-better-than-nothing tooltip hover. (I feel like that compound adjective could describe all of Laisin, not just the full-comment hovers.) But to that point -- I added in caching today! (It'd been gone since the App Engine days; for all in App Engine I didn't like, caching was cinch.) And I was even able to install everything locally and (less of a big deal) on Heroku without going crazy. (Well. Only a little crazy.) (When it comes to installing software and setting up environments, I def don't have this whole "bend machine to my will" thing. I've heard it's great though.)
January 15, 2013 You can now log in with your email address, rather than your username. (Apparently this was confusing to a few people. Also, I hate it when you can't do this on a web service.) Spent a bunch of time on the design of the profile pages, which I still don't love, but at least they don't look as terrible. You also can't follow yourself anymore; you can only edit your own profile, which, while less exciting, is probably more sensible. Re-wrote the text on the Subscription page and bumped up the price a bit (negative margins before!) I'd still like to build gift subscriptions.
January 14, 2013 New sign up and log in pages with prominent Facebook buttons, as "can I sign up with Facebook?" was an oft-requested feature. (So much so that it surprised me, for whatever that's worth.) I added in emails that alert you, a current Laisin user, when a Facebook friend joins Laisin, and then I (er, Lewis .. ) emailed all Laisin's current users, letting them know the new, exciting find-friends feature was live. And then I invited a handful more people to the site, including Greg, who brought up the stellar point of passwords having no length limit, since I'm hashing them anyway and Ryan, who sent a truely-amazing feedback email. A bunch of small, usability things fixed because of his feedback (and totally-justified confusion) and more to come. (A sample of the type of stuff: cursor: pointer on top-right nav menu, firmly getting rid of 'Add' in favor of 'Shelve,' and de-duping the books that appear in the slidy thing on top of profiles.) Super nitpicky feedback is incredibly valuable. More people should send more of it. (Doing so isn't mean, I promise!)
January 13, 2013 Right so Patrick helped me find whatever cert I was missing, download it, tack it on to the end of cert-stash, and be done with whatever Errno 185090050 was. (Sometimes, the web feels sooooo scotch-taped together.) But hey, I launched find friends from Twitter on Facebook! (Admittedly, there's currently no reason to follow people, except that's what you do on social web services, but that'll come someday. Probably.)
January 12, 2013 I managed to get "Find Twitter friends" working before leaving the apartment in the morning, and then I spent the afternoon working on finding Facebook friends from a Williamsburg coffee shop. Once I got that working, I built sign-up and login with Facebook, too; in addition to the credentials, I pull in your photo and full name from Facebook on both signup and login (on login, if you hadn't put in those things.) By the time I left the coffee shop, I had everything working locally (!!!!!!!) and a renewed appreciation for clear API documentation.

And then I went home, deployed, and saw this. What does that even mean?????
January 11, 2013 Ah, this was an exciting day, even though I didn't get as much done as I'd hoped. In the quick-wins category, I extended the length of sessions; mobile Safari, in particular, seemed to be a fan of the frequent log out, which ran counter to my goal of continued user engagement. (Mraah at your hatred of the web, Apple.) The rest of the day was spent meeting with people (not really related to Laisin, more "oh life") and then, in the late afternoon, I figured out how to tweet from the command line. That was great, but more important: it meant I got the Twitter API working. (And made it through Twitter's bizarre, birdwatching-field-guide themed documentation. Guys, I don't care as much about whether a User's more like a robin or a cardinal -- I just want to figure out how to call 100 of them!) I'd hoped to get "Find your Twitter friends" working today, but that didn't happen .. Oh -- I also closed off signups (but not invitations) because a few too many people signed up with clearly-fake email addresses. (Though to be clear to my future self: "a few too many" means two. Literally two.)
January 10, 2013 Spent a bunch of time trying to make /shelve and /reshelve look and act more "as they should": that the menus open and close when you'd expect them to, they save results when you'd expect them to, and the autocomplete looks like you'd expect it to. (Pinterest has done an amazing job of this, I think.) Separately, if you reshelve a book you've already shelved, I now assume you want to move it from the old shelf to the new one you've just specified; I had been creating a new book, so you'd have two books on two shelves, but no one was using the feature that way. (You users, you have funny preferences.) On main, you can see overflow comment text by clicking on the ellipses and waiting for a slow popup to show you the entire book. This seems like a poor solution, but hey, it works for now! Overall, this doens't feel like very much. I think I spent most of the day struggling with Jinja templates. Rarr!!
January 9, 2013 Feels like everything got redesigned today, but that's only because I'm still thinking in CSS (and everything's about 8px too high and 2px far right.) The main page looks a little different (I still don't like this version) and re-shelving works a tinch better and, more importantly, is faster. I'm not sure what else happened today.
January 8, 2013 CSS is no longer the worst thing ever in Firefox! (Sorry guys! (Switch to Chrome!)) Comment notifications now work, in that they go only to the people they're supposed to -- those who have shelved the book or previously commented on it -- and only once to each of those people. Eventually they'll only go to followers who've also shelved that book, but let's just say email overload isn't a problem I have right now .. I'm using Gravatar to pull in profile images, if you've got one, on signup. I'm looking forward to this; the gerbils had been manually adding profile images for the delinquints who didn't set them (gotta set that norm early, I figure) but they were getting tired. New profile pages are starting to take shape, though they're not very good yet. Finally, by "fixing" recommendations yesterday, I actually meant that every time a book was dedicated, a purchase was triggered if I'd seen your credit card number before. That might've been great for Laisin's business model in the short run, but it's probably not what I wanted in the longer term, so I stopped auto-purchasing recommended books.
January 7, 2013 This was organization day, after a ton of feedback from the past 10 days -- and, with a few days removal, the realization that "oh my god everything is the worst this site is so bad gah gah gah." (Or something like that, anyway.) The morning was spent sifting through feedback emails and making an intimidating list of everything that needs fixed. (It felt a little futile, as I'll never, ever get through everything on that list.)

On the plus side, things I did today: re-wrote all the emails, re-worked the mail_controller (which creates and queues the emails) to prepare for notifications, and added in an email that brand-new users will receive on signup. (The gerbils may've been sending that email before.) /username now redirects to that person's profile, e.g. /anthony is my brother. (What, this is a web service norm nowadays? Alright then.) /shelve, /reshelve, and /recommend all have pseudo tables and better searching when appropriate (and no text fields when not.) You can now create shelf from a popup on /shelve or /reshelve with an AJAX request (which means that the book you're shelving isn't lost to the ether as you create the new shelf!), recommendations can be purchased with a credit card again (gah, I broke that and didn't realize), I ask which type of book (hardcover, softcover, or Kindle) the recommendation should be, the text on the feedback form is a bit friendlier (thanks to Anthony's prodding), and I started a list of 'forbidden' usernames (e.g. /help, /abuse, /support, etc.) (And with all of that, I'm going to rest.)
January 5, 2013 The shelve page has a bunch of new, fancy stuff that (hopefully) makes it easier to find and shelve the correct book. The first version of search was "I'm Feeling Lucky": you give me a title string, and I'll pull the first results the Google Books API spits back. It wasn't very good. The second version included autocomplete, though only as a drop-down of titles. Based on Jason's "encouragement", I added cover images to those titles -- and then, eventually, a blob of information (title, author, big cover, truncated book description) on the left. Once you select the book, the cover image stays with you, to the right of the text box. Unfocusing and then focusing the search bar will bring back the search results automatically. (How do I do that? I'll never tell .. but my Javascript might.)
January 3, 2013 Happy New Year! The main page loads faster, first thanks to some query magic and then thanks to the removal of book likings. (What were book likings anyway?) The main page doesn't reload when the popup closes, which is probably a relief to all of you; instead, it'll show a confirmation when you've reshelved one of those books (but only then.) A new comment now generates an email to everyone who has previously commented on that BookShelving, which it should have been doing before but wasn't. (Sorry.) Books on profile pages are starting to look better; now, there's shelve/dedicate/buy/comment links on each book, titles and authors are displayed, and liked books are displayed but set apart from the standard shelves. (Recommended books should probably be like this too.) Autocomplete is turned off on the dedication and "tell a friend something about this book" fields. In each "so-and-so is following you" email, there's a link to follow that person back; it doesn't auto log you in yet (soon! too many things to make!) but at least the link's there.
December 30, 2012 Somewhat-hurried cafe updates this evening: I fixed the address-entry form, which wasn't working because of a stupid reason; started logging IPs on login -- I've got a few things planned for this, though nothing built/launched at the moment -- created a Notification collection, in the hope of 1) adding notifications to the site (as Anthony requested) and 2) tamping down the flow of emails from the site. Most of the "this person you're following has shelved this book" emails are off now, so guys -- you can stop filtering all that you get from Laisin now!
December 28, 2012 Replaced book buying links with Amazon icons, as it's been decided that 1) why is there a book icon on buy button? (Answer: because I hadn't yet found another/better icon); 2) who doesn't want to look at Amazon when buying books? (Answer: everyone wants to look at Amazon when buying books.) I don't think this is a one-month answer to the "what does buying look like on Laisin?" question, but it's definitely the ten-minute answer. I also put up a simple first-cut of follower and following pages, after Anthony complained that it's too hard to find people on the site. (It def is; it also needs fbook login, but that'll be a project for another day.) Those pages are extraordinarily cursory right now, and the grammar's wrong (people/person, oof.) but hey: they exist. Debugged The Missing Comment Issue, thanks to some direction from Steven. (I wasn't grabbing or saving comments on book re-shelvings. D'oh.) And finally: yay for surprise sorta-launching (while I was on an airplane, egads.) Feel like I'm really taking that "if you're not embarrassed when you launch" advice to heart ..
December 27, 2012 Knocked down the price of a monthly subscription, thanks to feedback from Dan. Entirely related, I sold my first subscription!!!!! Also emailed with Steven about Laisin-related things, which was quite helpful.
December 26, 2012 Now showing the login form on the index; anyone can sign up! (Well, that was true before, but now it's even easier to do so.) Fixed the profile display so that it'll correctly figure out if you're 1) looking at your own profile; and 2) if not, are you following the person? (Only works when logged in.) Slow day ..
December 25, 2012 Merry Christmas! I started to set up caching, but then I decided that, gaaaaah this'll be a longer and more frustrating project, and I really want to read my new books (eee!) and spend time with my family today. So that's what I did, for the most part. Smaller changes: /main only shows the last fifty bookshelvings; no one was getting through the bulk. Also messed with the autocomplete search results, in an attempt to make it better. (It's still not great; I'm fixing a ton of stuff manually in the db, after a book shelving's gone awry, which is a pain.) Built out followers/following and started sending emails when someone's decided to follow someone else (to me and to the "target" of the following. (All this language is soooo creepy. Even still.)) The gerbils who were sending the "your friend X added book Y" emails .. maybe manually .. shhh .. Finally added in the "recommend a book"/"add a book" squares on the have-read and to-read pages, depending on whether you're looking at your own or someone else's profile.
December 24, 2012 Added a type (Kindle, new softcover, new hardcover, used hardcover) to the shelf subscriptions, as this seems a relevant parameter. Also added in a "want to read" page (here's mine) and a "already read" page (here's mine) based on Hannah's suggestions from yesterday. (Which were super super super helpful.) The book display here's different from elsewhere on the site, and I'll have to decide on one version soon. (There's three going right now -- I know, I know.) One of the nice things about this version is that I'm showing who else has shelved the book below the cover. Since I know everyone on the site, basically, this seems a rather nice feature. You can't yet add shelves to the to-read page, which should be fixed. I was showing a datepicker for each book ("tell me when you finished this book?") but that jQuery started driving me crazy, and gaaah I'll get to that soon, but not today. I also re-worked the sitewide menu -- again, per Hannah's suggestion -- and added in tabs for /shelve to cover the other, semi-fake ways of adding books in to Laisin. (Photos and the "bookmarklet.") Started building out following/unfollowing, and was just getting ready to live test everything, when AWS/Heroku went down -- for 9 hours on Christmas Eve/early Christmas morning. I went to bed. Heroku, on the other hand .. poor guys.
December 23, 2012 Not much today; I added in email notifications for re-shelved books -- if your book gets reshelved, you get an email praising your taste -- which is nice, because I maaaaaaay have been sending those manually before. Maybe. (In my defense, there were only 10 people on the site, and I knew/know who knows whom anyway; to my chagrin, it was all of 20 lines of code, only two of them unique, basically.) On the bright side: vacations/holidays/breaks in routine are good motivaters: I added in these emails because I wasn't confident I'd be able to continue sending them both manually and in a timely manner. Ah, and! I made my first sales! Granted they were to my brother, and he was buying me Kindle books for Christmas, but still! Success!
December 22, 2012 Spent today battling with the stream; it's been ugly and terrible since the start, and -- at the end of the day -- I like this version slightly better than those that came before it. (It's still too Pinteresty to stay though.) The comments were the hardest part; right now, I'm truncating after a certain number of characters, adding in a linked '...', and throwing you over to the book profile page, which is a pretty shoddy solution. (Clicking the ... should expand the comment into something that looks reasonable; I'm just not sure what yet.) On the plus side of all this, I'm now a whiz at getting those book-action button to do what and look as I want.
December 20, 2012 Finished changing all references to the "Dedicated" shelf to the "Recommended" shelf. As nice was the idea of leaving a book for someone with the note inside, it felt too heavy, like some grand social gesture, and so it wasn't really done. (Cue the sigh and realization that "this is what it means to design social software.") I also shrunk the size of the rainbow autocomplete spinner; I'm still unsure how I feel about the rainbow, and it halts too much -- I always want to nudge it, when it slows at 5 o'clock -- but at least it's slightly less obtrusive. On bookshelves, the colored-library page with which I haven't yet figured out what to do, I'm now pre-loading the cover images that show up on hover. The "others who liked and shelved this book" section is now the "others who liked, shelved, and recommended this book" section; I've replaced the faces of people who have been recommended the book with those that have recommended the book. This code's pretty hacky, but one of the amazing things about having no users is that it doesn't matter! (Though there is a privacy breach here; even if you recommend a book privately, I'll still show you. So don't do anything too embarrassing for now!) On /main, I'm now referencing the initial comment as a note, which feels a bit better but probably isn't the final wording; that page is now a more traditional stream that shows all bookshelvings, rather than the most recent bookshelving or dedication per user. I'm a little skeptical of being overwhelmed by one or two users (erm, by myself) but I suppose the argument is that the inactive people will be inactive regardless, and having more "on top" of them is objectively better. If you decide to create a new shelf in the midst of shelving or reshelivng a book, that shelf is now auto-selected in the drop-down menu. (I'm not sure anyone will notice this is true, but it was driving me crazy before.) Finally, there's now category pages that list, in a rather ugly way, all the books in a particular category. I like this for book discovery in theory, though I'm worried that it'll just highlight how terrible the Google Books API changes are.
December 19, 2012 Spent most of the morning working on the buttons of /main, getting them to work with the new set-up. (It still took too long to do, but I can tell I'm getting faster.) There's lightboxes involved (meep?) for re-shelving, recommending, and buying the book; the hearts work in-line, and the comment button re-directs you to the associated /shelved page, auto-focusing the comment box. That interaction still isn't quite right, but it'll suit for now. In the process of doing all this, I realized I'm pulling all books for which you've put in an opinion (liking or dis-liking) for /likes/username, NOT the books you like. Oof. So that's fixed now. The /main flow shows the last book each person's shelved and the last book each person's recommended -- so, if you shelve or recommend multiple books, I'll only show the most recent. (There's some ugly code in place to do this.) Added in a StumbleUpon style book recommendation service too, after Zach kept asking what he should read. (Check it out from the bottom of /main which is awkwardly the only place it lives for now.) Got rid of the buy router, because dear god, what was that? (A placeholder, that's what.) Now I've got the credit card form and the Amazon affiliate link (with redirect tracking) because that's actually what I'd like people to use. The logged-out book page doesn't have a comment bar, as one didn't make sense and caused errors anyway, but does correctly show an 'Add to shelf' or 'Switch shelves' button depending on whether the user's logged in and has the book on a shelf already. The book index has been de-duped. It's still not very ideal visually, but hey, a start's a start. Finally, I took the numbers out of the book shelving (/shelved) URLs, so now they're just title-author-username, per Jason's protests. (He was right.)
December 18, 2012 Spent most of the day working on /main a new stream, and second design in as many days. It's still not very good, but it's at least less depressing than v1. There was some tweaking around which comment to show -- I wanted the original one, not the most recent -- and I started with divs but ended with a list. (Are those what everyone uses for layouts? Yes, it seems?) Added in a lightbox for re-shelving a book, though most of the other buttons work. This all seems very short. I thought I did more today?
December 17, 2012 So I'd had some trouble with the Google Books API; if it can't geo-locate the requester's IP , which can be particularly hard with Heroku dynamic IP switching something, it returns an error (500, I think?) I couldn't figure out where to pass the UNDOCUMENTED COUNTRY PARAMETER (seriously. guys.) so ended up just gluing a 'country=US' on the end of the URL. Seems totally reasonable, right? Right. Cleaned up image anti-aliasing (mainly by removing it) on the profile photos, as it made them look blotchy, and pushed a new stream, on which I spent most of the morning working. It's blocky, grey, and sorta depressing; I suspect it'll not be around for long. Finally, I added book cover images to the tooltips on bookshelves in an effort to make that page more information-dense. (Thanks for the feedback, Andrew.)
December 16, 2012 And then, in response to all the WONDERFUL AMAZING BEST-EVER feedback my very first users sent me, I fixed some idiotic things that were ugly, bad, or wrong.
December 14, 2012 Got a bunch of stuff done today in order to send out my first real-ish invitations! These included: adding a '.' to the find-an-email regular expression, which I realized was broken when I tried to invite someone who has a '.' in his email, sending more notification emails to users (e.g. when a comment's been received or a book's been reshelved) and to myself (e.g. for a new shelf that's created, and with different subject lines, so I don't get as much threading), and using default image for books without cover images and users without profile photos. On a whim, added in subscription commerce! Basically, you can pick a shelf -- only one of yours for now, though that should probably change -- and be sent one book, at random, each month, for $20. (I haven't an idea if this is at all appealing, but it was simple enough to build at least.) Changed linking on all the Jquery/Javascript and CSS files so they'll serve over SSL, and OMG finally got SSL working the way I want it to. Re-designed the "switch shelves" page to be simpler. (That first interface was truly horrible.) Oh, and, funny story for you: no sooner had I sent out an email announcing the site than I decided to wipe my production database. (It had old, non-compliant, blah data in it.) So I did by dropping the entire db, INCLUDING THE USER ACCOUNT. Oops. Fortunately Heroku makes it easy to drop and add extensions, so that's what I did with MongoHQ. A new username and pass
December 13, 2012 Stopped re-adding books I already had in the db (meep; that was an irritating bug.) Spent much of the day battling, and failing to best, my SSL certificate. I want some links auto-directed to SSL pages, and I can't for the life of me figure out how to get Flask, Heroku, and please-check-if-this-page-is-secure to play nicely together. (Right now, I get into these infinite redirect loops.) Gah, this is the part of all of this that I absolutely hate.
December 12, 2012 When I watched people use Laisin, they often couldn't tell the book-title fields would autocomplete; it was suuuuuper painful. So now, at least, there's rainbow spinner that shows up when you start entering text. I'm not sure how I feel about the rainbow, but the grey circles I found on the internet were boring and dull, and I didn't want to make my own gif. (I ended up experimenting with CSS transformations to get the spinning; it's pretty jerky, but it does, at least, work.) The dedication form now works with payments embedded -- having the same submit button work with and without the Stripe token, depending on user actions, drove me a bit crazy. And then I realized I can bind the Stripe stuff to the form later, rather than initially, and things became much much better. Started saving Amazon API responses, so I don't have to hit them as often -- at least in the ideal future, when I've got a sufficient number of users shelving books that this becomes a problem. Worked on the logged-out experience a bit; mostly small things like "if this person is logged in, and they request a book profile via /shelved, show them /book instead." (This is a better experience, I think.)
December 11, 2012 Started putting the privately-dedicate books on their own shelf, which makes it easier to hide them on the /profile pages. (They still show up on /bookshelves, which should get fixed at some point.) Added a prior_reader field to re-shelved books, both so I can keep track of that information and display it in the bookshelvings. (Also, game dynamics! If you can show up as someone re-shelving a book from you, will you shelve more books? No? Damn it.) Started building out something to let users ask one another questions about a book, but I think I'm going to put this on hold for now. (How's it actually useful?) Added tooltips to the /likes page, just as on the /profile page. These pages still aren't quite right, but hopefully they're a bit closer to something useful. Finally, I merged dedicate and dedicated pages into one and re-did the CSS for that and shelve; it took forever, but I think the design's much more clear. I suspect there's many more things like this that I should get to ..
December 10, 2012 Sooooo much CSS polish. There's gradients and drop shadows and look guys, Laisin is a real website! (That's what you're supposed to think now, at least.) Re-wrote the menu options in the upper-right of the page, though they probably need another revision or five. Spent most of the afternoon adding in private book shelvings, of which I'm super proud: you can now shelve a book privately, and everyone else will see a paper bag, rather than the cover; you'll see the cover peeking out of a paper bag. So witty, right? Right? Riiiight? More practically, this solves a problem I'd had with dedications: namely, I'd like the ones with purchases to be kept secret, but they were default-public.
December 9, 2012 Small changes today: cleaned up template inheritance a bit, got the Amazon Affiliate link working, made the way I pull in prices from Amazon more robust, added in another way to buy books from Laisin, fixed a bug in liking/disliking and fixed all the stupid errors I made in the other book-purchasing flow. (I hadn't really looked at this since moving over from Google App Engine, which wow! was a mistake. I guess this is why people talk about testing .. )
December 7, 2012 Got image uploads working on S3! Now I'm writing the book cover images, as well as the profile pictures that users upload, to an S3 bucket. I'm also using S3 for the static files -- HTML, CSS, Javascript, images -- that I'd been committing in the git repository. Other changes: I took a big piece of Django's Slugify method, for URLs, to use in making my pretty URLs. (Thanks Peter for the suggestion.) Started to poke at keeping dedciations a secret, but abandoned that because it's a more-invovled-than-it-should-be change. (There's at least a dedicated-hidden shelf now, which I'm not using.) Started re-routing users from the /invite page to the want to buy this book? page if they enter an email in the dedication field. (Those URLs are soooooo hacky.) Fixed the emails so that they're now using the URL, rather than the one. Cleaned up the last pieces of image display, so that my URL strings work either locally or in production. (That all drove me more crazy than it should've.)
December 6, 2012 Spent the morning fixing places that shelves had broken: dedications to users and email addresses, the top buttons on the /shelved and /book pages, etc. In the afternoon, I worked on the design of the /shelved and /book pages, trying to figure out if I need both. (I thiiiiink I do still.) I also worked on the design of the dedication pages -- they're much prettier now, generally -- and added in places where you can Add a new shelf and remove a book from the shelf.Right now, it's hard to add a book to multiple shelves; I should probably fix that .. Later in the evening, I started poking around at adding the images to S3, rather than to a local filestore. (Heroku doesn't give access to the filesystem.) I got the static files up and referenced and started to work on the book cover images, but by midnight, I was ready to head home.
December 5, 2012 Added bookshelves! Now, each user has a few bookshelves on which books can be put. The "starter shelves" are (currently): "My top 10", "Worth reading", "To read", "Read in 2012", "High school favorites", "Dedicated", "Uncategorized." Some were inspired by friends, others from Goodreads' behavior, and others from Pinterest behavior. I'm also keeping track of all books ever on a shelf, but I'm not planning to expose that in the app. There's no order to books (really BooKShelvings) on the BookShelfs yet - this is something important to add in. I was doing so much with BookShelvings that I created a pretty_url field for those, too, comprised of 'title-authors-username-[digit]'; right now I'm defaulting to '-0,' but that's sufficiently ugly that I should probably special case the first case of overlap .. Books can now be deleted, too. It's a little tricky to figure out where that option is, which should be changed, too. (I'm not actually deleting the Book, just the BookShelving, and switching some of the references too.)
December 4, 2012 Frustrating bug fixes today: character-encoding to the emails, so, e.g., Gödel, Escher, Bach sends correctly. (I think this book will forever be associated with character encoding in my mind.) There's now comments on the book page, bolstered by a supremely inefficient database retrieval. Filed under 'things I'll worry about when I have more than 5 users' for now ..
December 3, 2012 Bug fixes and flow improvements all over the place: the top navigation is now down in CSS with drop-downs; it needs more styling but is at least functional. There's a better /buy page for each book, and I put in pseudo-pages for the pieces I haven't yet built, along with a db object that tracks how many times each thing is requested. (This'll be helpful for feature prioritization, I hope.) On stream, the comment box is selected automatically when the 'Comment' button is clicked, and you're directed back to where you were if you submit a comment. Each user has a page that lists all the books they've liked, at /likes/, and there's a new feedback page separate from the bottom thing. (Everyone seemed confused by that, it doesn't really work, and I don't want to fix it.) I'm now tracking the number of times someone clicks on an Amazon link for a book, which might provide interesting data.
December 2, 2012 Deployed to Heroku, successful and finally! I know these new-fangled cloud services are supposed to be easy and understandable, but I wouldn't have figured out all the connections without some help ..
November 30, 2012 It was a day of making everything that worked with WebApp2 work again in Flask. Grabbing variables from requests, setting cookies, starting sessions, checking if a user is logged-in -- it's all slightly different in Flask, and I spent most of the day chasing down those errors and getting all of my functions working again. By the end of the day, I wasn't able to deploy to Heroku (why? whoooo knoooows) but I did have everything running happily and locally again.
November 29, 2012 Spent most of the day re-writing and (now to work with Flask (rather than WebApp2) and Mongo/MongoEngine (rather than the GAE datastore.) Cleaned up a ton of code too; there's parts that are ugly, but I thiiiiink it's looking better. Mailgun now sends my email; it was relatively painless to set up. Still nothing for caching. Just before I left, I got the entire file to load!
November 28, 2012 Perhaps most important, and not relevant to any code in Lesen, I got virtualenv working! (Gaaaah why does this whole installing-software thing take so long?) and pushed a Hello Flask to Heroku. Fixed the non-ASCII characters-in-titles problem by returning integer representations of each character and concatenating those, rather than hashing anything. Updated the action buttons (Like/Add/Buy/Comment/Dedicate/Date -- too many likely) on the book profile and stream pages. Fixed the email regular expression to accept addresses with '+' in them. Showing the user's bookmark color on all pages on which s/he is logged in. Started catching exceptions when there's no cover image to the book.
November 27, 2012 Cleaned up some code based on reading PEP 8 for eBay's Code Club. (Still gotta refactor big pieces of it at some point .. ) Title's with non-ASCII characters (e.g. Gödel, Escher, Bach) now use "Character encoding is hard" as the starting value for their has. (I should probably change this at some point, too.) Added a datepicker to the page after the book's been shelved, as well as the book profile pages, so you can tell me when you've read a book (if you so desire.) Re-architected some of the template CSS and soured slightly more on Jinja. Added in Boostrap's form style -- it's the only pieces of Boostrap in all of Lesen! -- because styling that blue glow myself sounded deadly. It all felt pretty light. :/
November 26, 2012 GAH I JUST SPENT AN HOUR on a colorpicker for the bookmark image on the top of the page. (You can do this on the edit profile page, and you entirely should.) It's entirely gratutious, and probably a shoddy use of time, but I love it! (Swooooooon.) Other things worth mentioning: each Book now has a fiction boolean, which I'm generating off the Amazon categories; the bookmark is made in pure CSS (to prepare for its color-swapping); I'd like to figure out how to add a nice drop shadow, even though it's two elements. (What's the CSS equivalent of "merge layers"?); autocomplete on book shelving and dedication fails gracefully; if you enter text, without selecting a book from the autocomplete list, it pulls the first book from that search query and shelves it, "I'm Feeling Lucky"-style; fixed the stream so that it shows both giver and recipient photos when a book's been dedicated; the large Amazon image is now (correctly) pulled; the book profile page looks a bit different -- not sure if I like this one better, but it gives me more space -- and the variable names of Book attributes were cleaned; passwords can be re-set on the profile page; dedications are now migrated with the books that are shelved as someone is invited to the site.
November 25, 2012 Started pulling a few more things from Amazon: large cover images, book descriptions (Google Books' API's weren't very good), categories/genres of the book (required making a new Category model.) Also added followers, following, bookshelves, and kudos into the database, though I'm not doing anything with them yet. Built skeletons for buy (ways you can buy the book) and shelved (leave a comment on the book after you've shelved it?) Both pages need a ton of work.
November 24, 2012 Changed the design of all the pages to something less Pinterest-framed and more book-framed. I'll give this one a week before deciding to scrap it. Added in the heart icons to the book-profile pages and finally got the profile images of the book-likers to show up properly. I started including empty squares everywhere, in the hope that my (two) users will upload profile pictures. I've now got to figure out how to crop those images .. I need squares. Every db object has a date_added field, which I'm going to use to sort things before displaying them. (I've not got that quite done yet.)
November 23, 2012 Bug fixes: books now display in the order in which they were added, rather than some other, random (db-driven) order; the edit profile link appears only on your own profile page; there's a (very preliminary) index that lists all the books on the site (not sure what I want to do with this yet); memcache updated after a dedication's been made; usernames and emails are automatically lower-cased when someone is signing up, and email addresses now accept non-alphanumeric characters (e.g. -, +, .) Liking and unliking books works again (thankfully) and photo thumbnails of the people who liked a book show up on the book profile page. (The code for both is suuuuuuuper ugly, but both work!) Started to re-write the copy on each page, but that looks like it'll be a much longer, more intense job.
November 22, 2012 More CSS changes around the way bookshelves display on profiles and at /bookshelf. Started to figure out what a book profile looks like, though that's still early and pretty scattered. Things look a bit nicer now, though only if you start to add information. (I'm not sure why you'd really do that yet, except if you're my mom. (Who did sign up! And is great.)) Also moved out all of the email sending into its own file, since the main file was/is getting messy.
November 21, 2012 Re-architected a little bit by creating a user_controller class that deals with all the messy data entry and checking around signing up, logging in, updating a profile, and setting an address. More of the payment information got moved to the payment_controller, and I added in a business model (/one-line function.) A bunch of CSS changes around the forms, added in while on a wifi-overloaded airplane.
November 20, 2012 Finished off payment detail- and address-collecting! It's suuuuuuuuper ugly but it works!! Also built an few admin pages to help me Wizard of Oz the purchaes. (What, you thought it might be programmatic? Psh.) I still need to build a bunch of error-validation on the address form fields .. Updated the stats page and admin-page styling both the slightest bit. Only a pre-specified set of usernames can access the stats and admin pages now. Fixed the Amazon price-pulling so that I'm getting the current Amazon price, not the list price, of the book. Added invitations. They're available at invite and as an easter egg when you enter an email address in the book dedication field. (That should really save the in-progress book dedication somewhere or somehow .. )
November 19, 2012 Added in a "this page needs more .. " feedback bar on the bottom right of the page that'll fire off an email to me with your suggestion. It's ugly, but it works! (I've an amazing surprise for the people who send me suggestions .. you should really check it out.) Started re-sizing the profile photos when they're uploaded toa width of 120px and a height of whatever's left. I'm still saving a copy of the original image/image size. The best part of this is that I've got the number of submit fields on /profile/edit down to one! Also added in emails to myself when all sorts of things happen on the site: people sign up, profiles are changed, books are added .. Built dedications, which allows you to put a book on someone else's shelf with a message. The book goes on the shelf, and an email is fired off to that person letting him/her know. (I'm toooootally going to need to shove all the email-related things out of the way soon. There's a lot of them.) In terms of smaller things, @LesenApp is set up for the moment if/when I want to do something with it. Built dedications (the ability to put books on someone else's shelf) but then mired myself in addresses and payments. Blah.
November 18, 2012 Got the hearts (for liking/disliking a book) working, as well as the autocomplete!! It's not a great API call or autocomplete function though; I might swap out autocomplete for some sort of "suggested items in a box below," as I suspect the current implementation will be very confusing.
November 17, 2012 Changed the bookshelf-drawing to choose book colors and widths based on the book itself. (The color's roughly based on a hash of the book's title; the width is a transformation of the book's page count.) Fixed a bunch of small bugs: display of author names on book profile pages, being unable to click the button to upload a profile photo (silly clear divs), BlobStore mime_type (more helpful for debugging than anything else), actually checking whether a User exists in the database, not just that they've got the correct hashed cookie, and probably some others too. Also added in user comments on the BookShelvings. It's not fancy AJAX-y yet, but it seems to work! Also fixed in the Amazon-affiliate link pulls by breaking down and parsing the XML that the Amazon API returns. (Why did we ever think XML was a good idea?) But hey – the links are good now!
November 16, 2012 Started to add to draw a bookshelf with the books in a user profile. It's early, but I think there's something interesting there.
November 15, 2012 Added in caching for the books, users, and book-shelving actions in the stream. (TBD whether I really set it up right, but it seems to be working now, locally with two users.) Also messed with the CSS more; I give some version of this design a 25% chance of sticking, which is higher than what the previous, black-Helvetica-on-white look had. Also changed the name of the site, temporarily, to 'Laisin,' a more American-friendly and phonetic version of 'Lesen.' Still looks a little odd to me, but I'll give it a few more days.
November 14, 2012 I'm now pulling down images from Google and then storing and serving them from the GAE Blobstore – no more direct-linking! I also cleaned up the display of the stream items (added in large images, made it a little more stream-y feeling.) Also added in affiliate links from Amazon, which required getting the Amazon Product Search API up and going. (Who thought XML was going to be a good thing? Gah. So frustrating.) Oh, also! I got // to work this morning! (Though I'll miss christina-books.)
November 13, 2012 It took most of the morning, but I've got profile-photo uploading working! You can now upload a very large photo that I can't resize it yet. (A challenge for another day.) I did the smallest bit of refactoring related to all of this but likely need to do much more. (Oof.) The stream now appears in reverse chronological order! And is on the front page, because things seemed sad and lonely. You can now re-shelve any book you'd like from that book's profile page, including one you've already got on your shelf. (Who am I to judge someone's desire to put up multiple books? Beside, I haven't figured out how to protect against that yet.) And then I got both liking and disliking working, at least as links from the book profile page!
November 12, 2012 Nothing quite worked today. GAE doesn't let you write to the server, so I'm still hot-linking the book covers from Google. (At least I took off those terrible page curls though.) Autocomplete was a disaster; I need help me with that. There's a (fairly boring) stream of BookShelving events now. Liking/unliking with hearts, even one per page, didn't work either. Right now, liking a book from a profile page works, but unliking doesn't. I'm not sure why. Gah.
November 3, 2012 Added images to the library pages, which are still hot-linked from Google. (Oops.) Added authors to the Book Profile pages. Began to re-do the architecture of this entire thing, and in the process broke everything. (It was the worst.)
November 2, 2012 Cleaned up the book listing tool, so it actually works now. You can add a book to a bookshelf multiple times, in part because I suppose one should be able to do that, and I couldn't get my query to work beside. Added /_stats, where I can keep an eye on the User and Book databases and feel good about how each of them are growing. Added book lists to profile pages, and opened up profile pages to all users. Built a page that shows all registered users on the site. Changed the verb to "Shelve" noun to "Bookshelf" rather than "Add" and "List" respectively. (C'mon; what am I building here anyway?) Added basic profile pages for the books, which are accessible, for now, by clicking on a book's title.
November 1, 2012 Set up the 'Bookmaker' class, which takes the HTTP Response and turns it into a proper book and the 'BookReader' class, which associates a user and a book. Fixed things more generally, so that you can again add books and see them on your list. Authors' names now display correctly, too. Fixed profile page and profiled editing so that they both (vaguely) work. You can now only add a book to a bookshelf once. Tested briefly with a second user, and things seem to work.
October 31, 2012 Back at it! Set up git and Github. Pulled and saved a few Google Books API responses so I could develop offline. (A Hurricane Sandy-necessitated move, but hopefully a good one overall.) Also started storing HTTP Responses, rather than just a few attributes, for posterity.
August 31, 2012 Added /changelog, began pulling information from the Google Books API when a book is added to the list (author listing is still really messed up, but at least a title, subtitle, page count, and ISBN are being stored!), fixed log in so logging in is again possible.
August 30, 2012 Continued adding decorator to logged-in pages. Managed to break git while trying to link it to github -- oops.
August 29, 2012 Added decorator to logged-in pages, fixed syntax on profile pages (though they're still pretty sparse, to say the least.) You can now enter free text as if it were a book title.
August 28, 2012 Started development! Worked on the log in, log out, cookie-setting, and password-hashing functions. Nearly all of that works.