Marketing Asset Management Script

A small internal tool at SnappPay that closed a recurring loop between marketing and engineering. Marketers uploaded banners, engineers spent hours renaming, resizing, and sorting them. I designed (and built) a script that turned a multi-day handoff into a few clicks.

Year 2023
Role Product Designer (writing code)
Stack Python · wxPython · Google Drive API

marketing asset managment

The real question

The marketing team uploaded promo banners into shared folders. Engineering then had to download, verify naming, check file format, confirm size limits, and re-sort everything before it could ship. Nothing was broken — it was just slow, error-prone, and demoralizing.

A workflow where nobody's at fault but everybody is frustrated is exactly the kind of workflow worth designing for.

Where the time was going

Pain

Inconsistent names

No naming convention meant engineers had to ask "which one is this?" on every drop.

Pain

Wrong file formats

JPGs landing in PNG slots silently broke downstream rendering.

Pain

Oversized assets

Banners above the size limit caused display issues no one caught until QA.

Pain

Manual sorting

Engineers re-folded every batch into the right subdirectories by hand.

Two trade-offs that shaped the fix

Tempting Build a full back-office uploader Right answer eventually, wrong answer for a 2-week problem.
Chose A naming convention + a script Shipped in days; bought the team months while back-office was being scoped.
Tempting Engineers run the script from the terminal Fastest to ship for engineers, blocks the marketing team from using it themselves.
Chose A wxPython UI on top of the script Marketing operates it directly. Engineering stops being the gate.

How the system works

01 · Standard

Naming convention

Defined with marketing: b-{store}-{type}.png — every banner self-describes.

02 · Source

Drive folders by type

In-store, online carousel, category full, half banner — each in its own folder.

03 · Verify

Format · size · name

Script checks PNG, under 3 MB, and matches the convention. Bad files surface with a reason.

04 · Sort

Auto-routed output

Verified banners land in the correct subfolder by filename prefix. No manual moves.

05 · UI

Source + destination picker

Marketing picks the folders, hits run, sees a list of recently uploaded files.

06 · Feedback

Inline error log

Errors appear in the UI with the exact file and reason — fixable without engineering help.

marketing asset managment

The verification logic

The core function — three checks, then a routed move. Small enough to read in one breath.

def verify_and_sort_banners(source_folder, target_folder):
    for filename in os.listdir(source_folder):
        filepath = os.path.join(source_folder, filename)

        if not filename.lower().endswith(".png"):
            print(f"Error: Unsupported format: {filename}")
            continue

        if os.path.getsize(filepath) > 3 * 1024 * 1024:
            print(f"Error: File exceeds 3MB: {filename}")
            continue

        if not filename.startswith("b-") or "-" not in filename:
            print(f"Error: Invalid naming: {filename}")
            continue

        target_subfolder = os.path.join(target_folder, filename.split("-")[1])
        os.makedirs(target_subfolder, exist_ok=True)
        shutil.move(filepath, os.path.join(target_subfolder, filename))
        print(f"Banner verified and moved: {filename}")

The full Phase 2 version added Google Drive download, a wxPython UI, and inline error reporting in the same flow.

Impact

Time

Hours → minutes

What had been a multi-hour engineering chore became a marketing-team self-serve action.

Accuracy

Errors caught upstream

Bad files fail at upload time, not in QA or production.

Ownership

Marketing operates it

Engineering stops being the bottleneck for a non-engineering problem.

The script is no longer in active use — a proper back-office system eventually replaced it. That's the point: it was an interim tool that bought the company time to build the right one.

Reflection

The interesting part of this project wasn't the Python. It was deciding that the right output for a product designer, in that moment, was a script — not a spec for engineering to build later. The team needed the problem solved, not handed off.

I'd carry forward two things: designers who can ship small internal tools shorten feedback loops nobody else can reach. And the best interim solutions are the ones that don't pretend to be permanent.