Working Ninja
2017-08-27T09:20:02

Getting Real by 37signals (available online) is a good mind stretcher. It provided much of the content for Rework (also by 37signals). Both books provided a lot of counter-intuitive business and development advice that works rather well in the software industry. Rework is one of my favorite business books with great illustrations (also available online).

Favorite chapters (from Getting Real):

Maybe just read it all =)

2017-08-27T08:56:34

Here's how I set up logging where:

  • Log files rotate nightly (at midnight).
  • We keep 10 total log files (as history).
import logging
import os

# Set up logging
logger = logging.getLogger(__file__)
handler_kwargs = {
    'filename': os.path.join(base_dir, 'file.log'),
    'when': 'midnight',
    'backupCount': 10
}
handler = handlers.TimedRotatingFileHandler(**handler_kwargs)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# Now log something
logger.info('Log something informative.')
logger.warning('Log a warning.')
logger.error('Log an error.')
logger.critical('Log a critical error.')

More examples and configurations: https://docs.python.org/2.7/library/logging.html

2017-08-27T08:44:20

Python 2.7 is not provided on CentOS 6 because Yum depends on Python 2.6. Simply installing 2.7 over 2.6 will break Yum. Thankfully, Red Hat provides us with an alternate installation method through their SCL project.

First, get Python 2.7 installed:
https://www.softwarecollections.org/en/scls/rhscl/python27/

Next, add the project path to the top of the script:

import sys
sys.path.insert(0,'/path/to/project')
sys.path.insert(0,'/path/to/project/env/lib/python2.7/site-packages')

Lastly, call the script via Cron:

cat /path/to/project/script.py | scl enable python27 python
2017-08-24T21:01:28

Here's a custom manager for a class (Change) that gets all approved changes where "today's date" falls between the Change.start_date and Change.end_date.

# models.py
import datetime
...
# Custom Change Manager that only pulls active, approved changes
class ApprovedChanges(models.Manager):
    def get_queryset(self):
        today = datetime.date.today()
        return super(ApprovedChanges, self).get_queryset().filter(
            approved=True,
            start_date__lte=today,
            end_date__gte=today
        )

class Change(models.Model):
    ...
    approved_changes = ApprovedChanges()

In our view, we could then call all changes for "today" that have been approved:

# views.py
def todays_changes(self):
   changes = Changes.approved_changes.all()
   ...

Source: https://docs.djangoproject.com/en/stable/topics/db/managers/

2017-08-24T07:47:57
# Simple List
', '.join([author.name for author in authors])

# Django
', '.join([author.name for author in book.author_set.all()])

Both will output "Author Name, Author 2 Name, ..., Author x Name"

2017-07-19T10:46:37

Let's say you add an element to the DOM via jQuery:

$("<button class="delete">Delete</button>").appendTo("foo");

And want to later remove it via a jQuery event. Calling $('.delete').on('click') will not fire the event. This is because .on() only looks for elements that were loaded initially with the DOM. To resolve you can use .live() for older version of jQuery or if you're using later versions of jQuery (1.7+), the following:

$(document).on("click", ".delete", function() { ... });

Since "document" existed when the DOM loaded a click on it will fire an event. Furthermore, since we specified the ".delete" CSS class for the selector arguement for the .on() event, the event will search through its descendents to find any elements with the ".delete" CSS class and execute our function.

Sources:
https://stackoverflow.com/questions/4900802/jquery-click-not-working-after-adding-element-to-the-dom
http://api.jquery.com/on/

2017-07-12T19:50:17

Using IUS (Inline with Upstream Stable)--a nifty repository provided by EPEL--we can upgrade beyond PHP 5.4 by first removing our current version of PHP, installing our preferred version (5.6 in our case), and then restarting Apache:

$ sudo yum remove php-cli mod_php php-common

$ sudo yum install mod_php56u php56u-cli php56u-mysqlnd

$ sudo apachectl restart

Sources:
https://www.digitalocean.com/community/tutorials/how-to-upgrade-to-php-7-on-centos-7
https://ius.io/GettingStarted/

2017-06-30T21:58:27

Renewing an SSL but can't recall exactly how it was filled out last time? Try the following:

openssl req -text -in request.csr

The above command will decode the CSR file and output its contents in human readable text. Enjoy!

More here: https://linux.die.net/man/1/req

2017-05-29T10:58:45

I just started my first Django project with Python 3 in earnest. One of the first things I have noticed is that reload isn't available by default from the Django shell. It needs to be imported:

>>> from importlib import reload
>>> reload(<module>)

This became a pretty tedious process and didn't always reload the module as expected. So, instead of reloading the shell and the module to run a command, I moved the commands that I was running into a custom Django management command. No more reloading =)

2017-05-02T17:37:37

The following code allows us to monkey patch the json() method that is returned by requests.post().

import requests
from mock import MagicMock


@mock.patch.object(requests, 'post')
def my_function(self, post):
    attrs = {'json.return_value': {'id': 1}}
    post.return_value = MagicMock(**attrs)

    r = requests.post()
    r.json()['id']

Source: https://docs.python.org/dev/library/unittest.mock.htmll#unittest.mock.NonCallableMock