django manage.py show stacktrace

This is a quick one more to save me time than anything else.

If you’re looking for how to get the stacktrace when a django manage.py command crashes, the –traceback option is what you’re looking for.

Use it like this:

python manage.py <methodname> --traceback

Family Friendly Internet: Free Tips for a Safer Home

These are the basic steps I have taken to getting family friendly internet and device usage in my home.  If you’re concerned that your kids are seeing things they shouldn’t or are tired of stumbling onto things yourself, these steps make it much less likely that anyones eyes will accidentally fall onto some of the terrible content that’s online.

What made me put these steps for Family Friendly Internet together?

I was trying to purchase school pictures this morning and mistyped the url from the form by one character.  You know what happens next; bam…ton’s of sinful garbage I don’t want to see spewed into my face during the morning coffee.  It’s not the first time it’s happened but I was finally motivated to try and make it the last time that garbage comes up by accident.

My Strategy

I do not believe it’s completely possible to block all of the filth.  If an intelligent person knows what they are doing, there are many ways to trick filters and other systems into letting you find content if you would like.  However, in this case, I have made it more difficult to either accidentally or intentionally find the garbage on my home network.

This only supplements the need for a strong policy on how and where devices can be used in the home.  In a world with so many social sites full of user uploaded content, at some point, anyone who wants to find the filth is going to find it.

  • Block Content at the Router
  • Limit Device Usage to Open Rooms

How to Block Content at the Router

Implement a content filtering policy at the router level so that every device connected to your network will have it’s content filtered.  Software filtering is too big of a pain since it requires an installation of every device.

Implement Basic Content Filtering

I use OpenDNS Family Shield to setup my router.  It’s very straightforward and there are really only two steps to getting free basic family filtering on your router.  Once this is setup, any device that connects to the wireless network will by default have a family friendly internet setup that can only connect to web domains that are considered appropriate for a family audience.

Point the router DNS static IP addresses to the OpenDNS family friendly filter IP Addresses:

208.67.222.123
208.67.220.123

Once the router is updated, restart your devices so that they will pick up the new DNS settings from the router.

Test after restarting using the link at the bottom of the OpenDNS Family Shield web page.

Note that this only “suggests” to every device on the network what DNS servers to use and that an adept user can override this from each device.

Limitations With Most Routers

Even after telling the router to use OpenDNS, safe sites like Google will still be able to find all the garbage.  While only the cached content will be there, using the safe search option on each search engine should keep the filth away.  In order to keep the garbage out of search engines, the average router cannot be setup to always force a Safe Search!

I am currently shopping for routers that can provide this level filtering.  I will update this post once I’ve found and tested a better router.  A koala router that was on kickstarter recently appears to be the best right now.

Restrict Device Usage

Finally, discourage or eliminate usage of devices behind closed doors.  No matter how good the routers get, there will be ways for smart kids to get past them.  Be especially careful with devices that have access to the mobile network since none of these steps will help with that problem.

In our home, we don’t allow devices into the bedrooms or bathrooms and when the kids are old enough for their own phones, they will stay downstairs as well.

 

 

No Scan Options: Scan from an HP OfficeJet to a Mac

I was getting “No Scan Options” when pressing the scan button on the machine. For awhile I thought the scanner was broken but I finally figured out how to scan from the HP OfficeJet to my Mac.

Why “No Scan Options”

The root of the problem is that you have to issue the command to scan from the computer and not from the scanner as with many other machines.

Once I tried things from the mac, it was really quite easy to get the HP OfficeJet to scan both from the document feeder and the single page glass scanner onto my mac.

How to scan from an HP OfficeJet to a Mac

Step 1.  Plug in the usb cord from the printer to your mac and make sure all of the latest software is installed.

Step 2.  Open System Preferences from Spotlight and navigate into “Printers and Scanners”.  If you are new to mac, to open Spotlight either use command+space or click on the magnifying glass in the top right.  Then search for anything.  For more on using spotlight, visit this page from apple: https://support.apple.com/en-us/HT204014.

Step 3.  Select the HP OfficeJet you are trying to scan from.  If you don’t see your printer, then go back and make sure that the printer is on, it is plugged in to your computer and the software drivers have all been installed.

Step 4.  From the scan tab, choose to “Open Scanner…”

Screen Shot 2016-03-23 at 5.30.12 PM

 

Step 5.  Scan away. Notice the option to use the document feeder or scan from the screen.
Screen Shot 2016-03-23 at 5.30.40 PM

 

Enjoy your scanner

Now that I know how to scan from my HP OfficeJet, I am much more effective at my home office.

Android ISO8601: How to Convert a Date to call APIs

I have needed to get a date in java converted to ISO8601 on android for awhile and struggled through a few different issues on my way to a working solution.

Since it’s an app that I’m asking people to download, I don’t like to increase the download size by even a few MBs. So even though Joda Time is great, I need a different way. In researching, I had to piecemeal a solution from various blogs and stackoverflow posts.

If you’ve ever been wondering,
– Does android have a standard way to convert to iso8601 format?
– Why isn’t it easier to get a UTC date that follows iso8601 so I can just call the APIs?
Then hopefully I can save you some time.

Android ISO8601: UTC SimpleDateFormat

The following is a straightforward way to get a UTC ISO8601 string of a date object without using any external libraries.


SimpleDateFormat ISO8601DATETIMEFORMAT = new SimpleDateFormat("yyyy/MM/dd 'T'HH:mmZ");
TimeZone  tz = TimeZone.getTimeZone("UTC");
ISO8601DATETIMEFORMAT.setTimeZone(tz);
String isoDate = ISO8601DATETIMEFORMAT.format( dtobject);

Android ISO8601: APIs Don’t like Arabic Chars

But wait, sometimes this still sends over Arabic characters like:

\u0662\u0660\u0661\u0666-\u0660\u0662-\u0662\u0665T\u0660\u0664:\u0665\u0661Z 

We don’t want that.  The solution turns out to be fairly simple.  Make sure that the SimpleDateFormat is always converting using the English language locale.

SimpleDateFormat ISO8601DATETIMEFORMAT = new SimpleDateFormat("yyyy/MM/dd 'T'HH:mmZ",Locale.ENGLISH);

**Credit goes to this StackOverflow Comment Suggesting Locale.English

Android ISO8601: A Convenience Class

To wrap it all up, here’s a convenience method.  It can be dropped in without adding any major overhead to your app in terms of size or performance.


public class AndroidISO8601Util{

      static SimpleDateFormat ISO8601DATETIMEFORMAT = new SimpleDateFormat("yyyy/MM/dd 'T'HH:mmZ",Local.ENGLISH);

      //Note: this method is not thread safe because SimpleDateFormat is not thread safe
      public static String getISO8601forAPI( Date dt){
      TimeZone tz = TimeZone.getTimeZone("UTC");
      ISO8601DATETIMEFORMAT.setTimeZone(tz);
      return ISO8601DATETIMEFORMAT.format( dtobject);
    }
}

Export Unsigned APK with Android Studio

For years I developed with eclipse and used the Android Tools option to Export Unsigned APKs.

Eclipse Android Tools had an easy option to Export an Unsigned APK
Eclipse Android Tools had an easy option to Export an Unsigned APK

I could then take the unsigned .apk file and upload it to Amazon’s developer console.

This was one of the last items I was still using eclipse for after over a year of Android Studio development.  I finally spent some time figuring out how to make the same thing happen without needing eclipse any longer.  I found many of the questions and answers on stackoverflow to be confusing and inaccurate.  For example, many seem to think that using the debug apk is the same as using the unsigned release apk…which is not accurate.

This is the comment that ended up helping me get it right:  http://stackoverflow.com/a/32202274/966122

Here’s How to Export Unsigned APK in Android Studio

1. Edit the gradle build file for the project to specify an unsigned release signing.

buildTypes {
release {
minifyEnabled true
proguardFiles 'proguard.cfg'
}

releaseUnsigned.initWith(buildTypes.release)
releaseUnsigned {
signingConfig null
}

}

2. Generate Signed Apk using the releaseUnsigned Build Type.  This is on the 3rd or 4th screen in the flow of version 1.4 of Android Studio.

Release unsigned apk in android studio
Release unsigned apk in android studio

Enjoy the Unsigned APK

Once the build finishes, there will be an unsigned apk in the location you specified. You can then upload that apk to an emulator or to Amazon to start the process of letting amazon sign the app.

Fix: part of the process of setting a preferred domain is to verify that you own error

I was trying to set naked domain as preferred domain in google webmaster tools and it showed an error “Part of the process of setting a preferred domain is to verify that you own http://example.com/. Please verify http://example.com/.”

If you’re not familiar with the terminology, a naked domain is the domain name without anything preceding it.  So no www., blog. or anything.  Just plain example.com is a naked domain.  I prefer this setup to the www. prefix when I can because it makes urls shorter and easier to read.  There’s still debate about it’s impact on SEO.

Fix the “part of the process of setting a preferred domain is to verify that you own” warning

First, create both the www.example.com and example.com versions of your site in google webmaster tools.  This is exactly the step I had skipped which led to the confusing error.

Make sure that both versions show up as verified sites in google.

Then, navigate into the www.example.com version of the site and change the site’s preferred domain to be example.com.

Add both sites to Set Naked Domain as Preferred Domain
See that both versions of site are verified

From there, things are straightforward and you shouldn’t see any errors.

Just go into each sites site settings.  Tap the site name, then Settings->Site Settings in the top right and choose to have the preferred site domain be naked domain.

More Information

For more information and tips about the whole process of setting your preferred site, there are many good detailed posts out there.  For example, this one.  However, I couldn’t find a clear answer to the problem I was running into while getting the “part of the process of setting a preferred domain is to verify that you own” error which led to this post.

cURL Example: Post a JSON File with Basic Auth

The web was missing a clear example that showed how to POST a JSON file with Basic Auth.  I love using cURL for it’s simplicity when trying out api’s and other services that I might want to use and have spent a decent amount of time figuring this particular usage out more than once.  If nothing else, I’ll be helping myself next time.

cURL JSON + Basic Auth Samples

In this case, I have a file locally that’s contents are the JSON which I want to be the payload of the POST.  Note that I do not want to POST the file as with a multi-part form upload.

curl -X POST -d @pathtofile https://user:pass@www.samplesite.com

Depending on the service you are calling, you might also need to set the Content-Type and encoding.

curl --header "Content-Type: application/json;charset=UTF-8" -X POST -d @pathtofile https://user:pass@www.samplesite.com

Finally, for troubleshooting, I’ve found it useful to either use the verbose -v for inspecting headers or –trace-ascii /dev/stdout for seeing the content of the request

curl -X POST -d @pathtofile https://user:pass@www.samplesite.com -v
curl -X POST -d @pathtofile https://user:pass@www.samplesite.com --trace-ascii /dev/stdout

Sample Output of –trace-ascii /dev/stdout command

== Info: Trying aa.xx.dd.bb…
== Info: Connected to xyz.abcd.com (aa.xx.dd.bb) port 443 (#0)
== Info: TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
== Info: Server certificate: xyz.abcd.com
== Info: Server auth using Basic with user ‘admin’
=> Send header, 241 bytes (0xf1)
0000: POST /demo HTTP/1.1
0031: Host: xyz.abcd.com
004f: Authorization: Basic Z3JlZW5oYXRhZG1pbjoxMjNBZG1pbiE=
0086: User-Agent: curl/7.43.0
009f: Accept: */*
00ac: Content-Type: application/json;charset=UTF-8
00da: Content-Length: 596
00ef:
=> Send data, 596 bytes (0x254)
0000: { “Students”: [{ “MIS_ID”: 201073, “Forename”: “Test”, “Surname
0040: “: “Tester”, “Email”: “xyz.abcd@gmail.com”, “YearGroup”: “6
0080: “, “Gender”: “M”, “Password”: “Ab@12” }, { “MIS_ID”: 161201, “Fo
00c0: rename”: “Tester”, “Surname”: “Test”, “Email”: “xyz.abcd@gm
0100: ail.com”, “YearGroup”: “6”, “Gender”: “F”, “Password”: “Ab@12
0140: ” }], “Staff”: [{ “TeacherID”: 220380, “Title”: “Mrs”, “Forename
0180: “: “Test”, “Surname”: “Tester”, “Email”: “xyz.abcd@gmail.
01c0: com” }], “Groups”: [{ “GroupID”: 63, “GroupName”: “6A Science”, ”
0200: GroupType”: “Class”, “GroupDescription”: “6A Science”, “PrimaryS
0240: taffId”: 220380 }] }
== Info: upload completely sent off: 596 out of 596 bytes
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 52 bytes (0x34)
0000: Cache-Control: no-cache, no-store, must-revalidate
<= Recv header, 47 bytes (0x2f)
0000: Content-Type: application/json; charset=utf-8
<= Recv header, 37 bytes (0x25)
0000: Date: Wed, 09 Dec 2015 16:02:52 GMT
<= Recv header, 40 bytes (0x28)
0000: Expires: Thu, 19 Jun 1980 19:19:19 GMT
<= Recv header, 18 bytes (0x12)
0000: Pragma: no-cache
<= Recv header, 15 bytes (0xf)
0000: Server: nginx
<= Recv header, 45 bytes (0x2d)
0000: Strict-Transport-Security: max-age=31536000
<= Recv header, 23 bytes (0x17)
0000: Vary: Accept-Encoding
<= Recv header, 20 bytes (0x14)
0000: Content-Length: 25
<= Recv header, 24 bytes (0x18)
0000: Connection: keep-alive
<= Recv header, 2 bytes (0x2)
0000:
<= Recv data, 25 bytes (0x19)
0000: {“i”:”4T7hz8tz8KU7ms2rz”}
== Info: Connection #0 to host xyz.abcd.com left intact
{“i”:”4T7hz8tz8KU7ms2rz”}%

Access ENOM DNS panel for Google Apps domain

I was unable to access the ENOM DNS console for a domain I bought through google years ago when they were still giving away google apps for free.

I was beating myself up for not being able to figure this out and the advanced DNS settings that used to be in Google Apps admin console have since been removed.

A quick call to enom ( after a not so quick wait time) got me exactly what I wish I had been able to find on the interwebs.  If you forgot your password or just cannot access enom DNS control panel from Google Apps dashboard, this should help.

How to Access ENOM DNS Console

If you’re trying to get in to change your nameservers, it’s easy.

  1. Visit https://access.enom.com
  2. Put your domain name and any password in along with the captcha.Get the password from your email.
  3. Change those nameservers or A records.  If you use google apps with the domain, only change the A records or the email and other functions of google apps will break.  Hopefully your hosting provider makes it easy to find the correct ip address to point the A record towards.

access enom DNS panel for google apps domain

 

iHome iBT74 Bluetooth Speaker: Why I bought

I bought an iHome iBT74 Bluetooth Speaker 2 months ago after doing quite a bit of comparison shopping online and then in the store. I ended up choosing this and so far I couldn’t be happier.

  • Price: The iHome bluetooth speaker is reasonably priced against the competition and with a little digging can normally be found for under $50. For the features it comes with, the price is very competitive.  It has a long battery life, you can answer phone calls, and the bluetooth connectivity with my phone has been more reliable than my previous speakers.
  • Sound: For a smallish speaker, the sound is quite good. You won’t ever be able to get a ton of base from little speaker like this, but for the size and mobility, I’ll take the sound quality.
  • Old School Cable: While I love the wireless bluetooth connections, sometimes I just need the reliability that of the old cable. I bought a few bluetooth speakers previously that only offered bluetooth connectivity and wished many times that I could plug in.

Biggest downside: For awhile I thought that there wasn’t any way to turn off the lighting. Even though the lights are pretty cool, there are times that I don’t want my speaker blasting out a bunch of light. There’s a button to cycle through different light schemes and one of the schemes is to have all the lights off.

In summary, if you’re looking for a pretty inexpensive but high quality bluetooth speaker that’s great on portability and reliable for connectivity.  Buy the iHome and carry the cable just in case the weather acts up.

Android Phonegap Native Timepicker

So I’ve been working on a simple android app and I finally got audacious and started to move beyond the basics. I was able to get an app in the store with just my HTML/JS/CSS skills pretty easily which makes phonegap a big success.

Anyhow, now my latest fiasco was to try and use the native android timepicker and while I’ve still got a ways to go, I wanted to post my working code that I also put back on a discussion I had with myself on the google group.

FWIW here’s what I’ve got working.

A simple TimePicker class with a showTimePicker method.

public class TimePicker {
private DroidGap mGap;

public TimePicker(DroidGap gap)
{
mGap = gap;
}

public void showTimePicker(){
mGap.showDialog(HelloWorldPlugin.TIME_DIALOG_ID);
}
}

A custom TimePickerDialog.OnTimeSetListener which is initialized with
knowledge of DroidGap too…

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mGap.sendJavascript(” callback javascript goes here!”);
}

Initialize and add the createdialog stuff like the android dialog
tutorial.

TimePicker timepicker = new TimePicker(this, appView);
appView.addJavascriptInterface(timepicker, “TimePicker”);

Then in the javascript, once phonegap loads, you can refer to the
timepicker:

window.TimePicker.showTimePicker();

Hope that Saves Somebody else some time or inspires somebody to show
me the ways of the plugin framework.

 

As I get better at this stuff, I might end up understanding how to do it within the plugin architecture but for now that’s it.

Cheers.