Saturday, March 2, 2013

Evernote Resets Passwords

From Evernote:

"Evernote's Operations & Security team has discovered and blocked suspicious activity on the Evernote network that appears to have been a coordinated attempt to access secure areas of the Evernote Service.

As a precaution to protect your data, we have decided to implement a password reset. Please read below for details and instructions."

I love Evernote and these things happen from time to time.  There's bad people out there.  It's not clear that the hackers even got access to sensitive data.  Evernote did the right thing by resetting passwords.

Am I worried? Nah.  I use a unique password for everyone of my sites all stored in 1Password + Dropbox.

Create a Simple HTTP Server in python

Short version:

python -m SimpleHTTPServer

Long version:

My background is ASP.NET web development.  When I think web server, I think of big heavy programs like IIS.  I knew that there were other webservers, but I never really considered using them for development.

At my new job, I've been doing Python + Google App Engine development (not asp.net).  This change in my career has led to a change in focus of what I read about.  I'm no longer hitting up the Microsoft C# sites anymore - not because they are bad -- just not relavent to my career.

About a week ago I came across an article from codeschool.com that talked about using node.js for a simple webserver.  This wasn't a big surprise to me -- I knew things besides IIS existed -- I had just never looked into it -- Up to this point I've just been using GAE as my webserver.

I fell into a rat hole of various ways to have mini-webservers.  Node.js had several options.  I pulled a few from Eric Allam's blog post (I found it via codeschool).  If you look down in the comments you'll find other simpler options to Eric's suggestion.  It went like this:

"You can using the filed module, but really Express is a better way to go, then again the connect module is the module actually serving the content in Express.  Looks like I've got options.  Then again, I'm really just interested in learning Python at the moment, I wonder if they have something? Sure enough - SimpleHTTPServer is the answer."

Nothing to do with Node.js, but that's how brainstorming and research goes.

Friday, February 8, 2013

Cron Job keeps failing because it cannot find library

I had a cron job that kept failing in google app engine.  This wasn't a production environment, but it was an appspot.  Turns out the fix was pretty simple.  Use Target in the cron.yaml to specify which version you want to run against.  If you don't, it just runs against the default version.  The default version doesn't have the code that the cron job was referencing so it fails.  The other fix is to just set your version to the default version.

https://developers.google.com/appengine/docs/python/config/cron#About_cron_yaml


Friday, February 1, 2013

Distinct keyword is not supported in 1.7.1

I've been trying to get the DISTINCT keyword working with my Google App Engine query.  Turns out that feature isn't available in 1.7.1 which is the version I'm using.  Upgrade to 1.7.4 to get it working.

db.Query(EntityName, projection = ("entityProperty",)).run(distinct=True)
Unknown configuration option ('distinct')
Edit
SDK 1.7.4 release notes
http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes

Friday, January 25, 2013

The Right Place to Look

I've been struggling with a project over the last few days.  I am dealing with new technology and a new business domain - a one-two punch that easily confuses me.

I put a lot of pride in my smarts - I never want to come off as a dumby, but sometimes you just have to really humble yourself and start asking questions.  I got over that issue long ago, its basically something you have to be comfortable with as a programmer.  For me, the struggle lately is finding the right person to ask, finding the right book, the right forum, or the right example code.  That can be the most difficult thing.

Inevitable when I find the right source, I berate myself thinking "duh! why didn't you look here first? It was so obvious!"

**********

Oh and I started a new job.  I am working at Webfilings.  An amazing place to work AND they have a nice little location here in my home town of Columbus, GA.  My local office has an open work environment, top of the line computers, free food and drinks, ping pong, XBox, beer Fridays, Aeron Chairs... the list goes on and on.  I never thought I'd work somewhere like this to be honest.

In you want to work here, take a look.

And if you are a company that needs a financial and regulatory reporting solution, check them out.  They offer an amazing product.

Saturday, January 19, 2013

Google App Engine Development site is slow to start up

My Google App Engine development website was taking a long time to load up.  During my testing of the app, I kept uploading documents.  After a few days of testing and developing the app, I had loaded several gigs of data into my dev server.  It kept taking longer and longer to turn on.

I didn't need the data and this simple fix cleared my datastore and made the startup nice and snappy.  You might want to occasionally do this if you notice a slow start up time.

dev_appserver.py --clear_datastore myapp

Tuesday, November 20, 2012

Basic CRUD app for Python and Google App Engine

I wrote a very basic CRUD app for Google App Engine in Python.  It's a basic sample on how to add, edit, delete, and list a single entity in GAE.  I didn't see anything like this on the web when I was learning GAE.  I hope this helps you.

You need python 2.7 installed and Google App Engine installed to get up and running.  I ran into one issue on Windows where nothing worked until I specified the version of python in GAE.  I didn't have this issue on Mac OS X.



basiccrud.py
import webapp2
import cgi
import datetime
import urllib

from google.appengine.ext import db
from google.appengine.api import users

#blog###################################################
class BlogPost(db.Model):
    title = db.StringProperty()
    content = db.StringProperty()
    date = db.DateTimeProperty(auto_now_add=True)

def BlogPostKey():
    return db.Key.from_path('Blog','default_blog')

def BlogById(id):
    return BlogPost.get_by_id(id,parent=BlogPostKey())


#PAGES#################################################
class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.write(
            '<html>'
                '<body>'
                    '<a href="/AddPost">AddPost</a>')

        BlogPosts = db.GqlQuery("select * from BlogPost order by date desc limit 10")

        self.response.write('<ul>')

        for post in BlogPosts:
            self.response.write('<li>{title} at {date} key: {key}<a href="/EditPost?id={key}">Edit</a></li>'
                .format(title=post.title,date=post.date,key=post.key().id()))

        self.response.write('</ul>')
        self.response.write('</body></html>')


class AddPost(webapp2.RequestHandler):
    def get(self):
        self.response.write(
            '<html>'
                '<body>'
                '<form action="/AddPost" method="POST">'
                    'TITLE:<input type=text name=title value=""/>'
                    '<br>CONTENT:<input type=text name=content value=""/>'
                    '<br><input type=submit text="submit"/>'
                '</form>'
                '</body>'
            '</html>')
    def post(self):
        title = self.request.get('title')
        content = self.request.get('content')
        newpost = BlogPost(parent=BlogPostKey())
        newpost.title = title
        newpost.content = content
        newpost.put()
        self.redirect('/')

class EditPost(webapp2.RequestHandler):
    def get(self):
        id = int(self.request.get('id'))
        newpost = BlogById(id)
        self.response.write(
            '<html>'
                '<body>'
                '<form action="/EditPost" method="POST">'
                    '<input type="hidden" value="{id}" name="id">'
                    'TITLE:<input type=text name=title value="{title}"/>'
                    '<br>CONTENT:<input type=text name=content value="{content}"/>'
                    '<br><input type=submit value="Save"/>'
                '</form>'
                '<form action="/DeletePost" method="POST">'
                    '<input type="hidden" value="{id}" name="id">'
                    '<br><input type=submit value="delete"/>'
                '</form>'
                '</body>'
            '</html>'
            .format(title=newpost.title,content=newpost.content,id=newpost.key().id()))
    def post(self):
        title = self.request.get('title')
        content = self.request.get('content')
        id = int(self.request.get('id'))
        newpost = BlogById(id)
        newpost.title = title
        newpost.content = content
        newpost.put()
        self.redirect('/')

class DeletePost(webapp2.RequestHandler):
    def post(self):
        id = int(self.request.get('id'))
        newpost = BlogById(id)
        newpost.delete()
        self.redirect('/')


app = webapp2.WSGIApplication([('/', MainPage),
                                ('/AddPost',AddPost),
                                ('/EditPost',EditPost),
                                ('/DeletePost',DeletePost)],
                              debug=True)
app.yaml
application: basiccrud
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: basiccrud.app