Subscribe: Anyway
http://www.laurenwood.org/anyway/feed/atom/
Added By: Feedage Forager Feedage Grade B rated
Language: English
Tags:
account  app  database  django  error  google account  google  it’s  password  people  pythonanywhere  site  system  wagtail 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Anyway

Anyway



meandering thoughts from Lauren Wood



Updated: 2017-02-01T18:31:27Z

 



Submitting news on XML.com

2017-02-01T18:31:27Z

I coded XML.com in Wagtail, a CMS based on Django. It works well for my needs and I like Python as a programming language. One of the big reasons I like Wagtail is that it includes a powerful enough but not overly complicated workflow with roles and a built-in moderation and preview system. But, I [...]

I coded XML.com in Wagtail, a CMS based on Django. It works well for my needs and I like Python as a programming language. One of the big reasons I like Wagtail is that it includes a powerful enough but not overly complicated workflow with roles and a built-in moderation and preview system.

But, I wanted a system where people could submit news items that would go into the moderation queue without needing to sign up for a login first. Fortunately, Wagtail makes that possible, and there’s a nice article by Erin Mullaney at Wagtail: 2 Steps for Adding Pages Outside of the CMS that details all the steps you need. It all worked nicely in more recent versions of Wagtail (thanks, Erin!) except for one part, the notification that the news item is in the moderation queue. That wasn’t a stop-ship item, so XML.com launched without those emails working.

I’ve now found the source of the problem. It turns out that when you submit a news item in this way, it doesn’t have a login identity attached to it (obviously, since there isn’t one). The send_notification function that sends the email uses templates, and these templates use the login identity of the author in the body of the email. Since that doesn’t exist, the whole function fails.

That means the solution is easy. The affected templates are wagtailadmin/notifications/submitted.txt and wagtailadmin/notifications/submitted.html, and Wagtail lets you customize the admin templates. I put my customized admin templates into a utils application, which contains all my utilities for the site. My utils/templates/wagtailadmin/notifications/submitted.txt file now has the content

{% extends 'wagtailadmin/notifications/submitted.txt' %}
{% load i18n %}

{% block content %}
{% blocktrans with page=revision.page|safe %}The page "{{ page }}" has been submitted for moderation.{% endblocktrans %}

{% trans "You can preview the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:preview_for_moderation' revision.id %}
{% trans "You can edit the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:edit' revision.page.id %}
{% endblock %}

Similar changes are necessary for the wagtailadmin/notifications/submitted.html file if you want to send HTML emails instead.




Django migrate tips

2016-05-10T16:22:26Z

If you read the documentation closely enough, of course all the information is there. Getting the order of operations right, however, can cause the odd issue. Developing Django apps means applying migrations, and those don’t always do what’s expected. In that case, you can roll back to the n-1 migration by using ./manage.py migrate [app_label] [...]

If you read the documentation closely enough, of course all the information is there. Getting the order of operations right, however, can cause the odd issue.

Developing Django apps means applying migrations, and those don’t always do what’s expected. In that case, you can roll back to the n-1 migration by using ./manage.py migrate [app_label] {n-1_migration_label}, then delete the nth migration, then edit the models.py to try again.

To clean up the database from some third-party app you decide you don’t want after all, you use ./manage.py migrate [app_label] zero to get rid of the migrations from that app. You have to run this before deleting the app from your settings.py file.




WordPress error

2016-04-25T21:40:11Z

One of my client websites suddenly started giving an error: Error establishing a database connection. When I went to the /wp-admin URL, the error was still there. This particular website is on shared hosting, so I logged into the CPanel and checked the database was still there. Then I checked the database and found some [...]

One of my client websites suddenly started giving an error: Error establishing a database connection. When I went to the /wp-admin URL, the error was still there.

This particular website is on shared hosting, so I logged into the CPanel and checked the database was still there. Then I checked the database and found some issues with some of the tables.

[site.wp_links] error: Table upgrade required. Please do "REPAIR TABLE `wp_links`" or dump/reload to fix it!
[site.wp_options] error: Table upgrade required. Please do "REPAIR TABLE `wp_options`" or dump/reload to fix it!
[site.wp_postmeta] status: OK
[site.wp_posts] status: OK
[site.wp_term_relationships] status: OK
[site.wp_term_taxonomy] error: Table upgrade required. Please do "REPAIR TABLE `wp_term_taxonomy`" or dump/reload to fix it!
[site.wp_terms] status: OK
[site.wp_usermeta] error: Table upgrade required. Please do "REPAIR TABLE `wp_usermeta`" or dump/reload to fix it!
[site.wp_users] error: Table upgrade required. Please do "REPAIR TABLE `wp_users`" or dump/reload to fix it!

Running those SQL queries on the appropriate database in phpMyAdmin fixed the problem. I don’t know whether the hosting company upgraded the database, or something happened with the automatic WordPress upgrade system, or if something else caused the problem.

[Update] There were a bunch of other errors that cropped up afterwards with the White Screen of Death; I had to call the hosting company to sort out the server-side errors causing those. It’s possible those errors were the original cause of the database problems, whatever they were.




ImportError

2016-04-22T23:04:33Z

I discovered another issue while deploying to PythonAnywhere (maybe it’s applicable to other PAAS providers as well). There was an odd ImportError when running manage.py. In the specific case I had, it showed up when running the tests with coverage: from Unipath import Path ImportError: No module named ‘Unipath’. It turned out I hadn’t installed [...]

I discovered another issue while deploying to PythonAnywhere (maybe it’s applicable to other PAAS providers as well).

There was an odd ImportError when running manage.py. In the specific case I had, it showed up when running the tests with coverage: from Unipath import Path ImportError: No module named ‘Unipath’. It turned out I hadn’t installed coverage in the virtual environment, which meant the system was using the default one. Installing coverage in the virtual environment as well fixed the problem.




Setting up on PythonAnywhere

2016-04-21T22:09:06Z

A checklist for moving a Django-Wagtail project to PythonAnywhere. There is documentation on the PythonAnywhere site; mine includes things I forget. Setup: development and testing on my laptop, staging and production on PythonAnywhere. The help files are pretty good, but I need my own checklist. Right now I’m in the staging mode, but at some [...]

A checklist for moving a Django-Wagtail project to PythonAnywhere. There is documentation on the PythonAnywhere site; mine includes things I forget.

Setup: development and testing on my laptop, staging and production on PythonAnywhere.

The help files are pretty good, but I need my own checklist. Right now I’m in the staging mode, but at some stage I’ll be moving to production. No point figuring out the same things twice!

  1. Develop on laptop in a virtualenv. Push commits regularly to bitbucket account. At some stage squash the migrations and clean those up. Four sets of settings: dev, testing, staging, production.
  2. Set up account on PythonAnywhere that allows the use of Postgres (it’s an add-on to a custom plan).
  3. Create virtualenv and set up staging web app. Delete virtualenv when you realise you didn’t use the right version of Python and the default is 2.7, not 3.5. Recreate the virtualenv with python 3.5.
  4. Clone the repository (using the ssh-keygen instructions). Redirect the public key to a file so you can copy it without line-breaks getting in the way.
  5. pip install -r requirements/production.txt (including psycopg2, which I didn’t need for development).
  6. Create the Postgres server, user, and database Don’t forget a strong password for the user (owner of the project database).
  7. Update the settings file with the database settings.
  8. Set the environment variables for the settings and the secret key (generator).
  9. Attempt to apply the migrations. This will show where you made mistakes on all the preceding steps.
  10. Fix the mistakes. Reload the web app to see if anything shows up.
  11. Set up the static file server. Check the static files are being served correctly.
  12. Create the Django superuser and log in.

The next step is data, of course.




Sun-dried tomato and olive tapenade

2016-01-02T20:46:12Z

Over the Christmas break I made a couple of dips, one of which got better reviews than the others. This is not a recipe for purists, since a real tapenade should have anchovies in it, but I didn’t have any and my family doesn’t like them anyway. None of the quantities are exact. The sun-dried [...]

Over the Christmas break I made a couple of dips, one of which got better reviews than the others. This is not a recipe for purists, since a real tapenade should have anchovies in it, but I didn’t have any and my family doesn’t like them anyway.

None of the quantities are exact. The sun-dried tomatoes were loosely packed in the measuring cup and I didn’t measure the olives, just drained the can and tossed them in the food processor. I didn’t chop anything before putting it in the food processor.

  • Approx 2 cups black olives (contents of one can, 398ml size). I used Californian black olives since those were in the cupboard, next time I’ll probably use Kalamata olives.
  • Approx 3/4 cup oil-packed sun-dried tomatoes; let most of the oil drip off but not all of it.
  • 5 cloves of garlic.
  • 2 tbsp capers

Process in a food processor until finely chopped. If it’s too dry, add a few drops of olive oil (or oil from the sun-dried tomatoes).




WordPress password protection

2014-11-17T16:50:43Z

WordPress was designed for public websites, not private ones, so password protection can be a little clunky. Fortunately there are plugins to help, but (as always) there are trade-offs to be made. When all you want to do is add a password to stop search engines indexing and outsiders reading the content, but you also [...]

WordPress was designed for public websites, not private ones, so password protection can be a little clunky. Fortunately there are plugins to help, but (as always) there are trade-offs to be made.

When all you want to do is add a password to stop search engines indexing and outsiders reading the content, but you also want make it as easy as possible for people to use, there’s the Password Protected plugin. As it says, it doesn’t protect the images or other uploaded content.

If you also want to protect the media, you will need to give people an account on the WordPress site (with username and password). Then you can use the htaccess edits detailed at http://www.idowebdesign.ca/wordpress/password-protect-wordpress-attachments/. This works, but in many cases you just don’t want to give lots of people accounts on the system, or make groups of people share an account. So it’s a trade-off — how important is password-protecting the images versus the administration overhead of user accounts with the associated username/password ease of use issues? If you do want to use usernames and passwords, perhaps giving a group of people a shared account, I’d recommend also using one of the plugins that helps with finer-grained access control, such as Members, to stop people being able to change things you don’t want them changing (such as passwords for the shared account).




GAE and OAuth 2 in the 2FA world

2014-10-30T21:27:09Z

I’ve been trying out Google App Engine, for which I signed up with the Google account where I just enabled 2FA. Of course, that means changing the way I update the uploaded trial application; the standard Google password has to give way to either a specific application-based password, or OAuth 2. OAuth 2 is obviously [...]

I’ve been trying out Google App Engine, for which I signed up with the Google account where I just enabled 2FA. Of course, that means changing the way I update the uploaded trial application; the standard Google password has to give way to either a specific application-based password, or OAuth 2. OAuth 2 is obviously (to me) the better way to go.

The documentation is reasonably straight-forward. It even works as documented, assuming you’re signed in with the right Google account on your default browser. My workflow is a little different — my main browser (Firefox) is signed into my main Google account, and I sign into my other Google account (which I’m using for this development project) on Chrome. Copying the URL from Firefox to Chrome to allow the appcfg application access to that Google account worked; it’s refreshing to see. I get tired of web applications that use some hidden JavaScript magic and give you nonsensical results if you copy a URL from one browser to another.

There’s something appealing about OAuth 2, even if it appears a little too magical at times (a bit like git; when it works it’s magical, when it doesn’t, good luck!)




2FA, the aftermath

2014-10-29T18:14:43Z

Two-factor authentication is generally seen as a good idea; there's a certain amount of hand-wringing over the fact that more people don't turn it on. The problem is, it's one of those things where you sign up for disruption over the next few days, for uncertain reward. The reward is uncertain because you can never [...]

Two-factor authentication is generally seen as a good idea; there's a certain amount of hand-wringing over the fact that more people don't turn it on. The problem is, it's one of those things where you sign up for disruption over the next few days, for uncertain reward. The reward is uncertain because you can never tell whether turning on two-factor authentication stopped someone hacking your account or not, just like you can't tell whether having an alarm company sign outside your house dissuades someone from breaking into it. My main email account has been on 2FA for ages, but I decided to add it to one of my secondary accounts as well, given that lots of people seem to mistakenly use that email instead of their own.

Tim suggested I used the authenticator app for my Google account 2FA, instead of using the SMS system. Just a hint: set it up while you still have access to your text messages since SMS is used for the bootstrapping authentication. You need to sign up for Google 2FA in the first place 'on a computer' (not specified whether a tablet is sufficient? I used the desktop). You are sent an SMS to authenticate yourself, and then you get another one when you want to authenticate the Authenticator app. After that, you don't need your SMS system, as long as you have the device with the Authenticator app on it.

But then there are the other apps, which now need application-specific generated passwords. Adium for Google Talk, for example, or email with Thunderbird. Setting each one up doesn't take long, but I'm sure some time in the future I will have forgotten and be wondering why I can't log in with a valid password.

And I understand what's going on, more or less, and think the short-term hassles are worth it. There are lots of people who don't have a mental model of passwords or authentication, who see only the pain and not the gain (since the gain is only in the absence of a potential future pain). Businesses are supposedly implementing 2FA fairly rapidly, but I'd be surprised if people in general were outfitting their personal accounts with 2FA at anything like the same rate. Mind you, I also suspect those surveys apply mostly to bigger companies in particular industries; anecdotal evidence I've heard points to a lower real adoption rate.




That was August

2014-09-04T22:33:19Z

August ended up busy, busier than I intended. Balisage was as usual full of interesting discussions although some of the people I’d hoped to see weren’t able to make it this year. I took part in a panel on MathML, figured out (finally) there is an overlap between the overlapping markup discussions and the DOM [...]

August ended up busy, busier than I intended. Balisage was as usual full of interesting discussions although some of the people I’d hoped to see weren’t able to make it this year. I took part in a panel on MathML, figured out (finally) there is an overlap between the overlapping markup discussions and the DOM Level 2 Range specification, and generally enjoyed myself.

Not long after that I left Design Science; I was disappointed it didn’t work out the way I’d hoped, but I did learn a lot about MathML and typesetting mathematics that I didn’t know before.

I’ve spent the last couple of weeks talking to people about different projects in healthcare and publishing, whether it’s something for me to work at or not. It’s good to be able to take time occasionally to see what’s out there, what people are working on. I’ve also been getting ready for the XML Summer School (there are still a couple of spots left in some of the courses if you’re interested in attending). And I’ve been working on learning plans for my children since their teachers are on strike. Khan Academy, Codecademy, and various workbooks to refresh last year’s skills to start with. I hope the strike is resolved before I have to do too much more planning.

At least we managed to spend a few weekends at the cabin for relaxation amongst all of that.