예제 #1
0
    def handle(self, *args, **kwargs):
        try:
            out_dir = args[0]
        except IndexError:
            print "Requires arg: <output directory>"
            return

        data = []

        qs = Profile.objects.enrolled().select_related('user')
        for profile in qs:
            docs = profile.user.documents_authored.filter(status='published')
            try:
                latest = docs.order_by('-date_written')[0]
            except IndexError:
                continue
            data.append((latest.date_written.strftime("%y-%m-%d"), profile))
        data.sort()
        data.reverse()
        rows = []
        for i, (date, profile) in enumerate(data[:250]):
            rows.append([str(i), str(profile.pk), profile.display_name])

            env = build_envelope(
                profile.user.organization_set.all()[0].mailing_address,
                profile.full_address())
            fn = os.path.join(out_dir,
                              "%03d-%s.jpg" % (i, profile.get_blog_slug()))
            with open(fn, 'w') as fh:
                fh.write(env.getvalue())
        write_csv(rows, os.path.join(out_dir, "manifest.csv"))
예제 #2
0
def get_mailing_file(request, mailing_id):
    mailing = utils.mail_filter_or_404(request.user, Mailing, pk=mailing_id)
    if mailing.has_file():
        response = HttpResponse(mimetype='application/zip')
        filename = mailing.get_file()

        # Compile special instructions
        special_instructions = []
        for letter in mailing.letters.all():
            if letter.recipient and letter.recipient.profile.special_mail_handling:
                special_instructions.append(letter.recipient.profile)
        if special_instructions:
            # Add/replace special instructions manifest.
            tmpdir = tempfile.mkdtemp()
            subdir = os.path.join(
                tmpdir,
                os.path.splitext(os.path.basename(filename))[0])
            os.makedirs(subdir)
            instructions_path = os.path.join(
                tmpdir,
                os.path.splitext(os.path.basename(filename))[0],
                "special_instructions.csv")
            rows = [["Name", "Address", "Special instructions"]]
            for profile in special_instructions:
                rows.append([
                    profile.display_name,
                    profile.mailing_address,
                    profile.special_mail_handling,
                ])
            utils.write_csv(rows, instructions_path)
            proc = subprocess.Popen([
                "zip",
                os.path.splitext(filename)[0],
                os.path.relpath(instructions_path, tmpdir),
            ],
                                    cwd=tmpdir)
            proc.communicate()
            shutil.rmtree(tmpdir)
        else:
            # No special instructions: remove them.
            proc = subprocess.Popen([
                "zip", "-d", filename,
                os.path.splitext(os.path.basename(filename))[0] +
                "/special_instructions.csv"
            ])
            proc.communicate()

        if settings.X_SENDFILE_ENABLED:
            response['X-Sendfile'] = filename
        else:
            with open(mailing.get_file()) as fh:
                response.write(fh.read())
        response['Content-Disposition'] = 'attachment; filename={0}'.format(
            os.path.basename(mailing.get_file()))
        return response
    task_id = tasks.generate_collation_task.delay(mailing.pk, request.path)
    return redirect("moderation.wait_for_processing", task_id)
예제 #3
0
파일: views.py 프로젝트: arthurlutz/btb
def get_mailing_file(request, mailing_id):
    mailing = utils.mail_filter_or_404(request.user, Mailing, pk=mailing_id)
    if mailing.has_file():
        response = HttpResponse(mimetype='application/zip')
        filename = mailing.get_file()

        # Compile special instructions
        special_instructions = []
        for letter in mailing.letters.all():
            if letter.recipient and letter.recipient.profile.special_mail_handling:
                special_instructions.append(letter.recipient.profile)
        if special_instructions:
            # Add/replace special instructions manifest.
            tmpdir = tempfile.mkdtemp()
            subdir = os.path.join(tmpdir, os.path.splitext(os.path.basename(filename))[0])
            os.makedirs(subdir)
            instructions_path = os.path.join(tmpdir, os.path.splitext(os.path.basename(filename))[0], 
                    "special_instructions.csv")
            rows = [["Name", "Address", "Special instructions"]]
            for profile in special_instructions:
                rows.append([
                    profile.display_name,
                    profile.mailing_address,
                    profile.special_mail_handling,
                ])
            utils.write_csv(rows, instructions_path)
            proc = subprocess.Popen(["zip", 
                os.path.splitext(filename)[0], 
                os.path.relpath(instructions_path, tmpdir),
            ], cwd=tmpdir)
            proc.communicate()
            shutil.rmtree(tmpdir)
        else:
            # No special instructions: remove them.
            proc = subprocess.Popen(["zip", "-d",
                filename,
                os.path.splitext(os.path.basename(filename))[0] + "/special_instructions.csv"
            ])
            proc.communicate()

        if settings.X_SENDFILE_ENABLED:
            response['X-Sendfile'] = filename
        else:
            with open(mailing.get_file()) as fh:
                response.write(fh.read())
        response['Content-Disposition'] = 'attachment; filename={0}'.format(
            os.path.basename(mailing.get_file())
        )
        return response
    task_id = tasks.generate_collation_task.delay(mailing.pk, request.path)
    return redirect("moderation.wait_for_processing", task_id)
예제 #4
0
    def handle(self, *args, **kwargs):
        try:
            out_dir = args[0]
        except IndexError:
            print "Requires arg: <output directory>"
            return

        data = []

        qs = Profile.objects.enrolled().select_related('user')
        for profile in qs:
            docs = profile.user.documents_authored.filter(status='published')
            try:
                latest = docs.order_by('-date_written')[0]
            except IndexError:
                continue
            data.append((
                latest.date_written.strftime("%y-%m-%d"),
                profile
            ))
        data.sort()
        data.reverse()
        rows = []
        for i,(date,profile) in enumerate(data[:250]):
            rows.append([
                str(i),
                str(profile.pk),
                profile.display_name
            ])

            env = build_envelope(
                profile.user.organization_set.all()[0].mailing_address,
                profile.full_address()
            )
            fn = os.path.join(out_dir, "%03d-%s.jpg" % (i, profile.get_blog_slug()))
            with open(fn, 'w') as fh:
                fh.write(env.getvalue())
        write_csv(rows, os.path.join(out_dir, "manifest.csv"))
예제 #5
0
파일: generate.py 프로젝트: catstar/btb
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)
예제 #6
0
파일: generate.py 프로젝트: Shidash/btb
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)