Esempio n. 1
0
def mass_mailing_spreadsheet(request, who=None):
    """ 
    Return a spreadsheet with one line per address for all users of a given
    type.
    """
    if not who:
        orgs = Organization.objects.mail_filter(request.user)
        return render(request, "correspondence/mass_mailing_spreadsheet.html", {"orgs": orgs})

    if who == "bloggers":
        qs = Profile.objects.bloggers()
    elif who == "bloggers_with_published_content":
        qs = Profile.objects.bloggers_with_published_content()
    elif who == "enrolled":
        qs = Profile.objects.enrolled()
    elif who == "invitable":
        qs = Profile.objects.invitable()
    elif who == "invited":
        qs = Profile.objects.invited()
    elif who == "waitlistable":
        qs = Profile.objects.waitlistable()
    elif who == "waitlisted":
        qs = Profile.objects.waitlisted()
    elif who == "needs_signup_complete_letter":
        qs = Profile.objects.needs_signup_complete_letter()
    elif who == "needs_first_post_letter":
        qs = Profile.objects.needs_first_post_letter()
    elif who == "needs_comments_letter":
        qs = Profile.objects.needs_comments_letter()
    elif who == "lost_contact":
        qs = Profile.objects.filter(lost_contact=True)

    if who != "lost_contact":
        qs = qs.filter(lost_contact=False)

    qs = qs.mail_filter(request.user)

    with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as fh:
        fname = fh.name
    utils.write_address_csv([p.full_address() for p in qs], fname)

    response = HttpResponse(content_type="text/csv")
    with open(fname) as fh:
        response.write(fh.read())
    os.remove(fname)
    response["Content-Disposition"] = "attachment; filename=%s-%s.csv" % (
        who,
        datetime.datetime.now().strftime("%Y-%m-%d"),
    )
    return response
Esempio n. 2
0
def mass_mailing_spreadsheet(request, who=None):
    """ 
    Return a spreadsheet with one line per address for all users of a given
    type.
    """
    if not who:
        orgs = Organization.objects.mail_filter(request.user)
        return render(request, "correspondence/mass_mailing_spreadsheet.html",
                      {'orgs': orgs})

    if who == "bloggers":
        qs = Profile.objects.bloggers()
    elif who == "bloggers_with_published_content":
        qs = Profile.objects.bloggers_with_published_content()
    elif who == "enrolled":
        qs = Profile.objects.enrolled()
    elif who == "invitable":
        qs = Profile.objects.invitable()
    elif who == "invited":
        qs = Profile.objects.invited()
    elif who == "waitlistable":
        qs = Profile.objects.waitlistable()
    elif who == "waitlisted":
        qs = Profile.objects.waitlisted()
    elif who == "needs_signup_complete_letter":
        qs = Profile.objects.needs_signup_complete_letter()
    elif who == "needs_first_post_letter":
        qs = Profile.objects.needs_first_post_letter()
    elif who == "needs_comments_letter":
        qs = Profile.objects.needs_comments_letter()
    elif who == "lost_contact":
        qs = Profile.objects.filter(lost_contact=True)

    if who != "lost_contact":
        qs = qs.filter(lost_contact=False)

    qs = qs.mail_filter(request.user)

    with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as fh:
        fname = fh.name
    utils.write_address_csv([p.full_address() for p in qs], fname)

    response = HttpResponse(mimetype='text/csv')
    with open(fname) as fh:
        response.write(fh.read())
    os.remove(fname)
    response['Content-Disposition'] = 'attachment; filename=%s-%s.csv' % (
        who, datetime.datetime.now().strftime("%Y-%m-%d"))
    return response
Esempio n. 3
0
def generate_colation(mailing):
    """
    Generates a zip file containing all of the letters and envelopes for a
    particular mailing.  The output has the following structure:
    mailings-YYYY-MM-DD/ 
      letters/ (all letters, individually)
      envelopes/ (all envelopes)
      postcards/ (any other postcard type)
    
      all_letters.pdf -- all letters of all kinds (not postcards) combined for 
                         double-sided printing
      manifest.csv    -- CSV file with sheet counts and names.
      addresses.csv   -- CSV file with all addresses, one column per line,
                         front-padded
    """

    tmpdir = tempfile.mkdtemp(prefix="colation")
    outname = "mailings-%s_%s" % (
        datetime.datetime.now().strftime("%Y-%m-%d"),
        mailing.pk,
    )
    outdir = os.path.join(tmpdir, outname)
    os.makedirs(outdir)  # also makes outdir

    envelopes = set()
    postcards = []
    letters = []
    manifest = defaultdict(int)
    for letter in mailing.letters.all():
        if not letter.get_file():
            continue
        address = letter.get_recipient_address()
        slug = slugify(address.split("\n")[0])
        if letter.is_postcard:
            postcards.append((slug, letter))
            continue
        letters.append((slug, letter))
        envelopes.add((slug, address, letter.org.mailing_address))
        count = get_pdf_page_count(letter.get_file())
        if count:
            manifest[(slug, address)] += count

    # Write manifest file
    if manifest:
        items = manifest.items()
        items.sort()
        rows = [(a.split("\n")[0].strip(), str((c + c % 2) / 2))
                for (s, a), c in items]
        utils.write_csv(rows, os.path.join(outdir, "manifest.csv"))

    # Write envelopes
    if envelopes:
        envelope_dir = os.path.join(outdir, "envelopes")
        os.makedirs(envelope_dir)
        for slug, addr, from_address in envelopes:
            env_fh = utils.build_envelope(from_address=from_address,
                                          to_address=addr)
            path = os.path.join(envelope_dir, "%s-envelope.jpg" % slug)
            with open(path, 'w') as fh:
                fh.write(env_fh.getvalue())

        # Write addresses CSV
        sorted_addresses = [a for s, a, r in sorted(envelopes)]
        utils.write_address_csv(sorted_addresses,
                                os.path.join(outdir, "addresses.csv"))

    # Write postcards
    if postcards:
        postcard_dir = os.path.join(outdir, "postcards")
        os.makedirs(postcard_dir)
        for slug, postcard in postcards:
            dest = os.path.join(
                postcard_dir, "{0}-{1}{2}.jpg".format(slug, postcard.type,
                                                      postcard.pk))
            shutil.copy(postcard.get_file(), dest)

    # Copy and combine letters
    if letters:
        letter_dir = os.path.join(outdir, "letters")
        os.makedirs(letter_dir)
        for slug, letter in letters:
            dest = os.path.join(
                letter_dir, "{0}-{1}{2}.pdf".format(slug, letter.type,
                                                    letter.pk))
            shutil.copy(letter.get_file(), dest)
        sorted_pdfs = sorted(glob.glob(os.path.join(letter_dir, "*.pdf")))
        utils.combine_pdfs(*sorted_pdfs,
                           add_blanks=True,
                           filename=os.path.join(outdir, "all_letters.pdf"))

    # Zip
    tmp_zip_path = "{0}.zip".format(outdir)
    zipbase = os.path.basename(outdir)
    proc = subprocess.Popen(["/usr/bin/zip", "-r", zipbase, zipbase],
                            cwd=tmpdir)  # zip adds ".zip"
    proc.communicate()

    # Clean up
    dest = os.path.join(settings.MEDIA_ROOT, "mailings",
                        os.path.basename(outname) + ".zip")
    try:
        os.makedirs(os.path.dirname(dest))
    except OSError:
        pass
    shutil.move(tmp_zip_path, dest)
    proc = subprocess.Popen(["rm", "-r", tmpdir])
    return os.path.relpath(dest, settings.MEDIA_ROOT)
Esempio n. 4
0
def generate_colation(mailing):
    """
    Generates a zip file containing all of the letters and envelopes for a
    particular mailing.  The output has the following structure:
    mailings-YYYY-MM-DD/ 
      letters/ (all letters, individually)
      envelopes/ (all envelopes)
      postcards/ (any other postcard type)
    
      all_letters.pdf -- all letters of all kinds (not postcards) combined for 
                         double-sided printing
      manifest.csv    -- CSV file with sheet counts and names.
      addresses.csv   -- CSV file with all addresses, one column per line,
                         front-padded
    """
    
    tmpdir = tempfile.mkdtemp(prefix="colation")
    outname = "mailings-%s_%s" % (
        datetime.datetime.now().strftime("%Y-%m-%d"),
        mailing.pk,
    )
    outdir = os.path.join(tmpdir, outname)
    os.makedirs(outdir) # also makes outdir

    envelopes = set()
    postcards = []
    letters = []
    manifest = defaultdict(int)
    for letter in mailing.letters.all():
        if not letter.get_file():
            continue
        address = letter.get_recipient_address()
        slug = slugify(address.split("\n")[0])
        if letter.is_postcard:
            postcards.append((slug, letter))
            continue
        letters.append((slug, letter))
        envelopes.add((slug, address, letter.org.mailing_address))
        count = get_pdf_page_count(letter.get_file())
        if count:
            manifest[(slug, address)] += count

    # Write manifest file
    if manifest:
        items = manifest.items()
        items.sort()
        rows = [(a.split("\n")[0].strip(), str((c + c%2)/2)) for (s, a),c in items]
        utils.write_csv(rows, os.path.join(outdir, "manifest.csv"))

    # Write envelopes
    if envelopes:
        envelope_dir = os.path.join(outdir, "envelopes")
        os.makedirs(envelope_dir)
        for slug, addr, from_address in envelopes:
            env_fh = utils.build_envelope(
                    from_address=from_address,
                    to_address=addr)
            path = os.path.join(envelope_dir, "%s-envelope.jpg" % slug)
            with open(path, 'w') as fh:
                fh.write(env_fh.getvalue())

        # Write addresses CSV
        sorted_addresses = [a for s, a, r in sorted(envelopes)]
        utils.write_address_csv(sorted_addresses,
                os.path.join(outdir, "addresses.csv"))

    # Write postcards
    if postcards:
        postcard_dir = os.path.join(outdir, "postcards")
        os.makedirs(postcard_dir)
        for slug, postcard in postcards:
            dest = os.path.join(postcard_dir,
                    "{0}-{1}{2}.jpg".format(
                        slug,
                        postcard.type,
                        postcard.pk
                    ))
            shutil.copy(postcard.get_file(), dest)

    # Copy and combine letters
    if letters:
        letter_dir = os.path.join(outdir, "letters")
        os.makedirs(letter_dir)
        for slug, letter in letters:
            dest = os.path.join(letter_dir,
                    "{0}-{1}{2}.pdf".format(slug, letter.type, letter.pk))
            shutil.copy(letter.get_file(), dest)
        sorted_pdfs = sorted(glob.glob(os.path.join(letter_dir, "*.pdf")))
        utils.combine_pdfs(*sorted_pdfs,
                add_blanks=True,
                filename=os.path.join(outdir, "all_letters.pdf")
        )
    
    # Zip
    tmp_zip_path = "{0}.zip".format(outdir)
    zipbase = os.path.basename(outdir)
    proc = subprocess.Popen(["/usr/bin/zip", "-r", zipbase, zipbase],
            cwd=tmpdir) # zip adds ".zip"
    proc.communicate()

    # Clean up 
    dest = os.path.join(settings.MEDIA_ROOT, "mailings",
            os.path.basename(outname) + ".zip")
    try:
        os.makedirs(os.path.dirname(dest))
    except OSError:
        pass
    shutil.move(tmp_zip_path, dest)
    proc = subprocess.Popen(["rm", "-r", tmpdir])
    return os.path.relpath(dest, settings.MEDIA_ROOT)