Example #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"))
Example #2
0
File: views.py Project: catstar/btb
def print_envelopes(request):
    if request.GET.get("ids"):
        try:
            ids = [int(i) for i in request.GET.get("ids").split(",")]
        except Exception:
            return HttpResponse("Error parsing ids parameter")
    else:
        return HttpResponse("Try adding 'ids' parameter")
    profiles = Profile.objects.select_related('user').in_bulk(ids)
    missing = []
    for pk in ids:
        if pk not in profiles:
            missing.append(pk)
    if missing:
        return HttpResponse("Can't find result for ids: %s" % missing)
    envelopes = []
    # NOTE: inefficient -- n+1 queries. Could be improved but not worth it for
    # the small expected query size.
    for pk, profile in profiles.iteritems():
        envelopes.append((utils.build_envelope(
            to_address=profile.full_address(),
            from_address=profile.user.organization_set.get().mailing_address),
                          "%s.jpg" % profile.get_blog_slug()))
    zipname = "envelopes-%s" % (datetime.datetime.now().strftime("%Y-%m-%d"))

    # Do it all in memory for fun and profit.
    zip_stringio = StringIO()
    zip_builder = zipfile.ZipFile(zip_stringio, "w")
    for jpeg, name in envelopes:
        zip_builder.writestr("%s/%s" % (zipname, name), jpeg.getvalue())
    zip_builder.close()
    response = HttpResponse(mimetype='application/zip')
    response.write(zip_stringio.getvalue())
    response['Content-Disposition'] = 'attachment; filename=%s.zip' % zipname
    return response
Example #3
0
def print_envelopes(request):
    if request.GET.get("ids"):
        try:
            ids = [int(i) for i in request.GET.get("ids").split(",")]
        except Exception:
            return HttpResponse("Error parsing ids parameter")
    else:
        return HttpResponse("Try adding 'ids' parameter")
    profiles = Profile.objects.select_related('user').in_bulk(ids)
    missing = []
    for pk in ids:
        if pk not in profiles:
            missing.append(pk)
    if missing:
        return HttpResponse("Can't find result for ids: %s" % missing)
    envelopes = []
    # NOTE: inefficient -- n+1 queries. Could be improved but not worth it for
    # the small expected query size.
    for pk, profile in profiles.iteritems():
        envelopes.append((utils.build_envelope(
            to_address=profile.full_address(),
            from_address=profile.user.organization_set.get().mailing_address
        ), "%s.jpg" % profile.get_blog_slug()))
    zipname = "envelopes-%s" % (datetime.datetime.now().strftime("%Y-%m-%d"))

    # Do it all in memory for fun and profit.
    zip_stringio = StringIO()
    zip_builder = zipfile.ZipFile(zip_stringio, "w")
    for jpeg, name in envelopes:
        zip_builder.writestr("%s/%s" % (zipname, name), jpeg.getvalue())
    zip_builder.close()
    response = HttpResponse(mimetype='application/zip')
    response.write(zip_stringio.getvalue())
    response['Content-Disposition'] = 'attachment; filename=%s.zip' % zipname
    return response
Example #4
0
def print_envelope(request, user_id=None, reverse=None, address=None):
    if user_id:
        user = utils.mail_filter_or_404(request.user, Profile, pk=user_id).user
        to_address = user.profile.full_address()
    else:
        to_address = request.GET.get("address", address)
    if not to_address:
        raise Http404
    from_address = user.organization_set.get().mailing_address
    if reverse:
        from_address, to_address = to_address, from_address

    stringio = utils.build_envelope(to_address=to_address, from_address=from_address)
    response = HttpResponse(content_type="image/jpeg")
    response.write(stringio.getvalue())
    response["Content-Disposition"] = "attachment; filename=%s-envelope.jpg" % slugify(to_address.split("\n")[0])
    return response
Example #5
0
    def handle(self, *args, **kwargs):
        try:
            out_dir = args[0]
        except IndexError:
            print "Requires arg: <output directory>"
            return

        qs = Profile.objects.enrolled().annotate(
            count=Count('user__documents_authored'))

        for i, profile in enumerate(qs):
            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())
Example #6
0
def print_envelope(request, user_id=None, reverse=None, address=None):
    if user_id:
        user = utils.mail_filter_or_404(request.user, Profile, pk=user_id).user
        to_address = user.profile.full_address()
    else:
        to_address = request.GET.get('address', address)
    if not to_address:
        raise Http404
    from_address = user.organization_set.get().mailing_address
    if reverse:
        from_address, to_address = to_address, from_address

    stringio = utils.build_envelope(to_address=to_address,
                                    from_address=from_address)
    response = HttpResponse(mimetype='image/jpeg')
    response.write(stringio.getvalue())
    response['Content-Disposition'] = 'attachment; filename=%s-envelope.jpg' % \
            slugify(to_address.split('\n')[0])
    return response
    def handle(self, *args, **kwargs):
        try:
            out_dir = args[0]
        except IndexError:
            print "Requires arg: <output directory>"
            return

        qs = Profile.objects.enrolled().annotate(
                count=Count('user__documents_authored')
        )

        for i,profile in enumerate(qs):
            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())
Example #8
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"))
Example #9
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

    manifest = {"letters": [], "postcards": []}
    for letter in mailing.letters.all():
        if not letter.get_file():
            continue
        details = {
            "recipient": letter.get_recipient_address(),
            "sender": letter.org.mailing_address,
            "type": letter.type,
            "file": letter.get_file(),
            "id": letter.id,
        }
        details["slug"] = slugify(details["recipient"].split("\n")[0])
        if letter.is_postcard:
            manifest["postcards"].append(details)
        else:
            manifest["letters"].append(details)

    # Write envelopes
    if manifest["letters"]:
        envelope_dir = os.path.join(outdir, "envelopes")
        os.makedirs(envelope_dir)
        unique_envelopes = set((d["slug"], d["recipient"], d["sender"])
                               for d in manifest["letters"])
        for slug, addr, from_address in unique_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 postcards
    for key in ("postcards", "letters"):
        if not manifest[key]:
            continue

        file_dir = os.path.join(outdir, key)
        os.makedirs(file_dir)
        for details in manifest[key]:
            dest = os.path.join(
                file_dir, "{0}-{1}{2}.{3}".format(
                    details["slug"], details["type"], details["id"],
                    ("jpg" if key == "postcards" else "pdf")))
            shutil.copy(details["file"], dest)
            # Replace 'file' in manifest with zipfile-relative path
            details["file"] = os.path.relpath(dest, outdir)

    # Make combined letters pdf.
    if manifest["letters"]:
        sorted_pdfs = sorted(
            glob.glob(os.path.join(outdir, "letters", "*.pdf")))
        utils.combine_pdfs(*sorted_pdfs,
                           add_blanks=True,
                           filename=os.path.join(outdir, "all_letters.pdf"))

    # Write manifest file
    with open(os.path.join(outdir, "manifest.json"), 'w') as fh:
        json.dump(manifest, fh, indent=2)

    # 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)
Example #10
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)
Example #11
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)
Example #12
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

    manifest = {"letters": [], "postcards": []}
    for letter in mailing.letters.all():
        if not letter.get_file():
            continue
        details = {
            "recipient": letter.get_recipient_address(),
            "sender": letter.org.mailing_address,
            "type": letter.type,
            "file": letter.get_file(),
            "id": letter.id,
        }
        details["slug"] = slugify(details["recipient"].split("\n")[0])
        if letter.is_postcard:
            manifest["postcards"].append(details)
        else:
            manifest["letters"].append(details)

    # Write envelopes
    if manifest["letters"]:
        envelope_dir = os.path.join(outdir, "envelopes")
        os.makedirs(envelope_dir)
        unique_envelopes = set(
            (d["slug"], d["recipient"], d["sender"]) for d in manifest["letters"]
        )
        for slug, addr, from_address in unique_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 postcards
    for key in ("postcards", "letters"):
        if not manifest[key]:
            continue

        file_dir = os.path.join(outdir, key)
        os.makedirs(file_dir)
        for details in manifest[key]:
            dest = os.path.join(file_dir,
                "{0}-{1}{2}.{3}".format(
                    details["slug"],
                    details["type"],
                    details["id"],
                    ("jpg" if key == "postcards" else "pdf")
                ))
            shutil.copy(details["file"], dest)
            # Replace 'file' in manifest with zipfile-relative path
            details["file"] = os.path.relpath(dest, outdir)
            
    # Make combined letters pdf.
    if manifest["letters"]:
        sorted_pdfs = sorted(glob.glob(os.path.join(outdir, "letters", "*.pdf")))
        utils.combine_pdfs(*sorted_pdfs,
            add_blanks=True,
            filename=os.path.join(outdir, "all_letters.pdf")
        )

    # Write manifest file
    with open(os.path.join(outdir, "manifest.json"), 'w') as fh:
        json.dump(manifest, fh, indent=2)

    # 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)