Extending Webpy Blog App With Cookbook Features

Summary: [Modified](https://github.com/Bill Seitz/webpy-blog-plus) stock "blog-plus" app in WebPy to add standard cookbook features I always need, so that future newbies don't have to spend time on them.

Started from Webpy For Simplest Thing in May'2012.

Feeling like solving too many generic problems (there). Raise the idea of taking an existing sample app and adding lots of these cookbook pieces, hosted on GitHub for moving forward and sharing. (May28)

  • reviewing existing sample apps to see if any include much of this stuff.... (May29)
    • hmm, maybe this "MLSS" HR-candidate-tracking system has some good bits... on the other hand it probably does "too much" of its own domain for purposes of helping someone start something of their own. So take stuff from there and apply to something else really thin.
  • leaning toward picking blog app to add stuff to. Have a single blog with multiple authors - anyone can register and then add to the single stream. So keep the current single table of entries, adding a user_id field, then have the users table.
    • start with raw version of the app. Copy all the bits to my machine.
    • Build SQLite db from the schema.sql. Tweak code to use SQLite instead of MySQL
    • run - get working start page.
    • create post - on save, get <type 'exceptions.TypeError'> at / - unsupported operand type(s) for -: 'datetime.datetime' and 'unicode' at line delta = now - then which is inside the function utils/datestr() - local var then is a unicode string.
      • that function says it's supposed to: Converts a (UTC) datetime object to a nice string representation. - so it shouldn't be passed as unicode. Perhaps the issue is with using SQLite instead of MySQL? Just do a hack of the function for now: {{{ elif type(then).name in ('str', 'unicode'): #hack by Bill Seitz, expect '2012-05-29 20:42:13.352449' d_format = '%Y-%m-%d %H:%M:%S.%f' then = datetime.datetime.strptime(then, d_format) }}}
    • now loading index page gives me list
    • but not getting post.id in the index template, so links to view/edit entries doesn't work!
      • db record doesn't have id value. Note schema uses AUTO_INCREMENT which raised issues with me before. Change to AUTOINCREMENT - get syntax error!... Finally got it by changing sql file to {{{ CREATE TABLE "entries" ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, }}}
      • now get post.id and link works fine
    • create GitHub https://github.com/Bill Seitz/webpy-blog-plus do commit
      • someone else did a nice tweak of the .gitignore, so merge that
    • next: sessions - done (May30)

next: CSRF

  • interesting thread from last year with no follow-up
  • do a new-entry post successfully
  • try a hack - view-source in Chrome, save file to desktop, edit Form tag to have fully-qualified URL for post, view desktop form in Safari, fill in and Post - get CSRF rejection - yay!
    • go back into Chrome to try again the right. Argh, getting CSRF rejection!
      • go back to form again, view-source, has csrf-token of e87a799f39404dad82068cba06cb653f. Do hard-reload of form, view-source again, token hasn't changed value. Try post again. Get reject again.
    • go into Safari (having quit it), load form. View-source, see CSRF token is that same value. Fill in form, post - get CSRF rejection!
    • commiting and posting to see if someone can help.
      • Jason M saves the day. I Commented: Hmm, under a scenario where someone's opening multiple forms at the same time (e.g. opening edit forms for multiple blog posts and moving text around before saving any), you'd actually want instance-specific tokens, right? (I'm not going to worry about that case for now, but I could see it being an issue, right?)
  • Jason M submits other improvements. Ugh they break. His submits fixes.
    • me re-test (Jun05)
      • do insert the right way - works. Do Edit the right way - works.
      • save fresh create-post form to local, tweak Post URL, leave in the CSRF hidden field value. Open form in other browser, put in data, submit - get error, but not the expected CSRF rejection error. Instead get <type 'exceptions.KeyError'> at /new - csrf_token because of trying to get session["csrf_token"] when it doesn't exist. (That's because he changed from using the pop function to avoid removing the entity, but now loses the check-if-exists step...)
      • he's working on some new validation code that will fix this

Next: faking user-login and logout to see how to display session.user_name in regular templates and in base template.

  • now have handlers, and display in /index.html template - pushed. (Jun05)
  • put into base template successfully, take out of index - pushed. (Jun05)
  • now have display in base template use conditional logic (show login vs name-and-logout) - pushed. (Jun05)

Add directory for static assets (Jun18).

Jul22: have some authentication stuff working in Webpy For Simplest Thing - need to adapt it over here, plus add requirement for cryptacular.

Apr'2014: have made a variety of changes

  • change naming patterns for classes/methods
  • add a config.py
  • add those authentication bits in an auth.py
    • but this is having problems with sessions.
  • May8: move auth.py bits back into single main file. Commit and push back up to GitHub. https://github.com/Bill Seitz/webpy-blog-plus

Edited:    |       |    Search Twitter for discussion