Importing addresses from a text file: Difference between revisions

From Scribus Wiki
Jump to navigation Jump to search
No edit summary
m (added link to ScribusGenerator (mail merge) script.)
 
(14 intermediate revisions by 2 users not shown)
Line 1: Line 1:
A [[http://nashi.altmuehlnet.de/pipermail/scribus/2007-February/022355.html question on the mail-list]] asked about how to import a series of addresses from an external file. One of the ways to do this would be with some kind of database, although for simpler projects, creating the database, then creating the script to use it would be too much work.
{{Scripting Index}}


This script, importadd.py, uses a simple text file with a particular format, parsing the addresses and then creating a text frame for each. As written, the script opens a new document, then creates new pages. One could modify it to make use of an existing document as well.
A [http://nashi.altmuehlnet.de/pipermail/scribus/2007-February/022355.html question on the mail-list] asked about how to import a series of addresses from an external file. One of the ways to do this would be with some kind of database, although for simpler projects, creating the database, then creating the script to use it would be too much work. An alternative would be to list the addresses in a spreadsheet, define a scribus template for the final wanted layout, and use the [https://github.com/berteh/ScribusGenerator/ Scribus Generator] script to create separate documents (or a single merged document) for each address automatically.
 
The script below, '''importadd.py''', uses a simple text file with a particular format, parsing the addresses and then creating a text frame for each. As written, the script opens a new document, then creates new pages. One could modify it to make use of an existing document, or not only place these addresses, but also other page elements as you go, such as the mass mailing envisioned by the List questioner.


The format of the address text file is that it begins immediately with the first address, and the address is laid out as it will be on the page. After the address, there is a single blank line separating it from the next address. This is important because this blank line -- and it must be a blank line and no characters -- is the flag to tell the script that the address is finished, go ahead and make a new page, make a text frame and put the address in it.
The format of the address text file is that it begins immediately with the first address, and the address is laid out as it will be on the page. After the address, there is a single blank line separating it from the next address. This is important because this blank line -- and it must be a blank line and no characters -- is the flag to tell the script that the address is finished, go ahead and make a new page, make a text frame and put the address in it.
Line 46: Line 48:
</pre>
</pre>
===Notes===
===Notes===
* One of the rigid features is that the text file must be named <tt>addr.txt</tt>, but one could easily add a FileDialog to be able to input a filename. So, before the line:
* One of the rigid features is that the text file must be named <tt><b>addr.txt</b></tt>, but one could easily add a File Dialog to be able to input a filename. So, before the line:
<pre>
<pre>
file = open('addr.txt', 'r')
file = open('addr.txt', 'r')
Line 58: Line 60:
file = open(selectfile, 'r')
file = open(selectfile, 'r')
</pre>
</pre>
* The <tt>page</tt> variable is there only to make sure that a new page isn't created at the beginning, since we already did that with the <tt>scribus.newDoc</tt> command.
* The <tt><b>page</b></tt> variable is there only to make sure that a new page isn't created at the beginning, since we already did that with the <tt><b>scribus.newDoc</b></tt> command.
* In case you're wondering why this <tt>readline</tt> and concantenation works without inserting carriage returns, it's because Python reads in a newline at the end of each line. This also explains why the test for a blank line looks for <tt>'\n'</tt>.  
* In case you're wondering why this <tt><b>readline</b></tt> and concantenation works without inserting carriage returns, it's because Python reads in a newline at the end of each line. This also explains why the test for a blank line looks for <tt><b>'\n'</b></tt>.  
* This <tt>while 1:</tt> construct looks rather clumsy, since we just get out of the while loop with a <tt>break</tt> command, but it's shown as an example in the Python text I use as a reference. Similarly, we didn't <tt>file.close()</tt> but relied on the fact that the script was done at that point -- considered acceptable in Python.
* This <tt><b>while 1:</b></tt> construct looks rather clumsy, since we just get out of the while loop with a <tt><b>break</b></tt> command, but it's shown as an example in the Python text I use as a reference. Similarly, we didn't <tt><b>file.close()</b></tt> but relied on the fact that the script was done at that point -- considered acceptable in Python.
* The <tt>scribus.createText</tt> variables are (x, y, width, height), where x and y refer to the upper left hand corner of the frame, and units are points for this script, but are taken from the <tt>scribus.newDoc</tt> command.
* The <tt><b>scribus.createText</b></tt> variables are (x, y, width, height), where x and y refer to the upper left hand corner of the frame, and units are points for this script, as seen in the <tt><b>scribus.newDoc</b></tt> command.
* The whole script will fail if you're not running it from Scribus, and yes, you could use something like
<pre>
try:
    import Scribus
.
.
.
except:
</pre>
with a message to tell people to use it in Scribus, but really, no one gets hurt if it fails. I try to keep the coding as concise as I can, and the "meat" of this script is only 20 lines. I think it's good to learn how to understand the Traceback messages that Python generates -- not likely to be the last time you will see one.


===An Example Address File===
===An Example Address File===
* Once again, the file should contain nothing other than the addresses. The blank line between addresses has no other characters -- it needs to satisfy this <tt>if info != '\n'</tt> test (technically, needs to fail the test) in order to recognize that the address has finished. For this reason, there also needs to be two blank lines at the end, and there can be no blank lines in the middle of the address. '''Note the need for two blank lines at the end -- perhaps the way that Python reads EOF.'''
* Once again, the file should contain nothing other than the addresses. The blank line between addresses has no other characters -- it needs to satisfy this <tt><b>if info != '\n'</b></tt> test (technically, needs to fail the test) in order to recognize that the address has finished. For this reason, there also needs to be two blank lines at the end, and there can be no blank lines in the middle of the address. '''Note the need for two blank lines at the end -- perhaps due to the way that Python reads EOF.'''
* The addresses came from a website showing formats for postal addresses to various countries, so as far as I know do not identify any living persons.
* The addresses came from a website showing formats for postal addresses to various countries, so as far as I know do not identify any living persons.
<pre>
<pre>

Latest revision as of 17:17, 13 February 2016

This article is part of the Scripts series.

A question on the mail-list asked about how to import a series of addresses from an external file. One of the ways to do this would be with some kind of database, although for simpler projects, creating the database, then creating the script to use it would be too much work. An alternative would be to list the addresses in a spreadsheet, define a scribus template for the final wanted layout, and use the Scribus Generator script to create separate documents (or a single merged document) for each address automatically.

The script below, importadd.py, uses a simple text file with a particular format, parsing the addresses and then creating a text frame for each. As written, the script opens a new document, then creates new pages. One could modify it to make use of an existing document, or not only place these addresses, but also other page elements as you go, such as the mass mailing envisioned by the List questioner.

The format of the address text file is that it begins immediately with the first address, and the address is laid out as it will be on the page. After the address, there is a single blank line separating it from the next address. This is important because this blank line -- and it must be a blank line and no characters -- is the flag to tell the script that the address is finished, go ahead and make a new page, make a text frame and put the address in it.

Here is the script:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 File importadd.py
 Created 2007-02-17
 Gregory Pittman
 imports addresses from text file
 puts them in text frame
 adds new pages as needed
 The format for addr.txt is a plain text file beginning with the first address,
 one line of the file for each line of the address. No blank lines inside the
 address, and a single blank line between the addresses and *two* blank lines after
 the last address. 
"""
import scribus

if scribus.newDoc(scribus.PAPER_LETTER, (10,10,20,20),scribus.PORTRAIT, 1, scribus.UNIT_POINTS, scribus.NOFACINGPAGES, scribus.FIRSTPAGERIGHT):

    file = open('addr.txt', 'r')
    add = ''
    page = 0
    while 1:
        info = file.readline()
        if not info: break
        if info != '\n':
            add = add + info
        else:
            if page:
                scribus.newPage(-1)
            A = scribus.createText(60, 100, 200, 100)
            scribus.setText(add, A)
            scribus.setTextAlignment(scribus.ALIGN_LEFT, A)
            scribus.setFont("Luxi Sans Regular", A)
            scribus.setFontSize(12, A)
            add = ''
            page = page + 1

Notes

  • One of the rigid features is that the text file must be named addr.txt, but one could easily add a File Dialog to be able to input a filename. So, before the line:
file = open('addr.txt', 'r')

you could add this (with or without this filter for files ending in '.txt'):

selectfile = scribus.fileDialog("Select Your Address File", "*.txt")

then modify the next line:

file = open(selectfile, 'r')
  • The page variable is there only to make sure that a new page isn't created at the beginning, since we already did that with the scribus.newDoc command.
  • In case you're wondering why this readline and concantenation works without inserting carriage returns, it's because Python reads in a newline at the end of each line. This also explains why the test for a blank line looks for '\n'.
  • This while 1: construct looks rather clumsy, since we just get out of the while loop with a break command, but it's shown as an example in the Python text I use as a reference. Similarly, we didn't file.close() but relied on the fact that the script was done at that point -- considered acceptable in Python.
  • The scribus.createText variables are (x, y, width, height), where x and y refer to the upper left hand corner of the frame, and units are points for this script, as seen in the scribus.newDoc command.
  • The whole script will fail if you're not running it from Scribus, and yes, you could use something like
try:
    import Scribus
.
.
.
except:

with a message to tell people to use it in Scribus, but really, no one gets hurt if it fails. I try to keep the coding as concise as I can, and the "meat" of this script is only 20 lines. I think it's good to learn how to understand the Traceback messages that Python generates -- not likely to be the last time you will see one.

An Example Address File

  • Once again, the file should contain nothing other than the addresses. The blank line between addresses has no other characters -- it needs to satisfy this if info != '\n' test (technically, needs to fail the test) in order to recognize that the address has finished. For this reason, there also needs to be two blank lines at the end, and there can be no blank lines in the middle of the address. Note the need for two blank lines at the end -- perhaps due to the way that Python reads EOF.
  • The addresses came from a website showing formats for postal addresses to various countries, so as far as I know do not identify any living persons.
Monsieur Jean Durand
25 Rue des Fleurs
33500 LIBOURNE
FRANCE

Sr. D. Alvaro Blanco Ruiz
Luna 10 - 3°
28300 ARANJUEZ (MADRID)
SPAIN

John Smith
100 MAIN ST
PO BOX 1022
SEATTLE WA 98104
USA

Herrn 
Ebelhard Wellhausen
Wittekindshof
Schulstrasse 4
32547 Bad Oyenhausen
GERMANY

Sig. Mario Rossi
Viale Europa, 22
00144 ROMA, RM
ITALY

M. Andrée TROMMER
BP 5019
L-1050 Luxembourg
LUXEMBOURG

Mr. Walter C. Brown
49 Featherstone Street
LONDON
EC1Y 8SY
ENGLAND