makememe 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: makememe
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: A tiny zero-dependency CLI for generating memes via the free memegen.link API. Agent-friendly.
5
5
  Project-URL: Homepage, https://pypi.org/project/makememe/
6
6
  Project-URL: memegen.link API, https://api.memegen.link
@@ -67,7 +67,7 @@ meme <template> "top line" "bottom line" [-o out.png]
67
67
 
68
68
  | Flag | Meaning |
69
69
  |------|---------|
70
- | `-o, --out` | output file (default `meme.png`) |
70
+ | `-o, --out` | output file (default: a unique file in a temp folder, so it never writes into your current directory) |
71
71
  | `--bg URL` | use a custom background image instead of a template |
72
72
  | `--ext` | `png` (default), `jpg`, `webp`, or `gif` |
73
73
  | `--style` / `--font` | template style variant / font override |
@@ -106,7 +106,7 @@ The tool is designed to be parsed:
106
106
  - **`--json` mode** prints a single JSON object:
107
107
 
108
108
  ```json
109
- { "path": "meme.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
109
+ { "path": "/tmp/makememe/meme-ab12cd.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
110
110
  ```
111
111
 
112
112
  `--list --json` returns the template catalog as JSON; `--print-url --json`
@@ -48,7 +48,7 @@ meme <template> "top line" "bottom line" [-o out.png]
48
48
 
49
49
  | Flag | Meaning |
50
50
  |------|---------|
51
- | `-o, --out` | output file (default `meme.png`) |
51
+ | `-o, --out` | output file (default: a unique file in a temp folder, so it never writes into your current directory) |
52
52
  | `--bg URL` | use a custom background image instead of a template |
53
53
  | `--ext` | `png` (default), `jpg`, `webp`, or `gif` |
54
54
  | `--style` / `--font` | template style variant / font override |
@@ -87,7 +87,7 @@ The tool is designed to be parsed:
87
87
  - **`--json` mode** prints a single JSON object:
88
88
 
89
89
  ```json
90
- { "path": "meme.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
90
+ { "path": "/tmp/makememe/meme-ab12cd.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
91
91
  ```
92
92
 
93
93
  `--list --json` returns the template catalog as JSON; `--print-url --json`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "makememe"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "A tiny zero-dependency CLI for generating memes via the free memegen.link API. Agent-friendly."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -44,15 +44,17 @@ uv tool install makememe
44
44
  Output:
45
45
 
46
46
  ```json
47
- { "path": "meme.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
47
+ { "path": "/tmp/makememe/meme-ab12cd.png", "bytes": 12345, "url": "https://api.memegen.link/..." }
48
48
  ```
49
49
 
50
50
  3. **Tell the user the path** (and show the image if the surface supports it).
51
51
 
52
52
  ## Key flags
53
53
 
54
- - `-o out.png` choose the output filename (default `meme.png`). Pick a
55
- descriptive name when generating several.
54
+ - By default the image is saved to a temp folder (`<tmp>/makememe/`) with a
55
+ unique name, so it never clutters the user's working directory. The path is
56
+ in the output — report it to the user. Use `-o path.png` only if the user
57
+ wants it saved somewhere specific.
56
58
  - `--bg <image-url>` — use a custom background image instead of a template;
57
59
  pass caption lines as usual.
58
60
  - `--ext png|jpg|webp|gif` — output format.
@@ -23,12 +23,23 @@ import argparse
23
23
  import json
24
24
  import os
25
25
  import sys
26
+ import tempfile
26
27
  import urllib.parse
27
28
  import urllib.request
28
29
 
29
30
  API = "https://api.memegen.link"
30
31
 
31
32
 
33
+ def default_output(ext):
34
+ """A unique output path in a grouped temp folder, so we never write into the
35
+ user's project/root dir and never clobber a previous meme."""
36
+ d = os.path.join(tempfile.gettempdir(), "makememe")
37
+ os.makedirs(d, exist_ok=True)
38
+ fd, path = tempfile.mkstemp(prefix="meme-", suffix=f".{ext}", dir=d)
39
+ os.close(fd)
40
+ return path
41
+
42
+
32
43
  def get_version():
33
44
  """Read the installed package version; fall back gracefully from source."""
34
45
  try:
@@ -134,8 +145,8 @@ def build_parser():
134
145
  ap.add_argument("template", nargs="?",
135
146
  help="template id (see --list), or any id when using --bg")
136
147
  ap.add_argument("lines", nargs="*", help="text lines, in order")
137
- ap.add_argument("-o", "--out", default="meme.png",
138
- help="output file (default meme.png)")
148
+ ap.add_argument("-o", "--out", default=None,
149
+ help="output file (default: a temp folder, not your current dir)")
139
150
  ap.add_argument("--bg",
140
151
  help="custom background image URL (uses the 'custom' template)")
141
152
  ap.add_argument("--ext", default="png", choices=["png", "jpg", "webp", "gif"])
@@ -190,8 +201,10 @@ def _run(argv=None):
190
201
  print(url)
191
202
  return
192
203
 
204
+ out = args.out if args.out else default_output(args.ext)
205
+
193
206
  try:
194
- n = download(url, args.out)
207
+ n = download(url, out)
195
208
  except Exception as e:
196
209
  # a 404 almost always means a bad template id — point the user/agent at --list
197
210
  hint = None
@@ -199,10 +212,10 @@ def _run(argv=None):
199
212
  hint = (f"template '{template}' not found (404). "
200
213
  "Run `meme --list` to find the correct id.")
201
214
  if args.json:
202
- out = {"error": str(e), "url": url}
215
+ payload = {"error": str(e), "url": url}
203
216
  if hint:
204
- out["hint"] = hint
205
- print(json.dumps(out))
217
+ payload["hint"] = hint
218
+ print(json.dumps(payload))
206
219
  sys.exit(1)
207
220
  msg = f"download failed: {e}\nurl was: {url}"
208
221
  if hint:
@@ -210,9 +223,9 @@ def _run(argv=None):
210
223
  sys.exit(msg)
211
224
 
212
225
  if args.json:
213
- print(json.dumps({"path": args.out, "bytes": n, "url": url}))
226
+ print(json.dumps({"path": out, "bytes": n, "url": url}))
214
227
  else:
215
- print(args.out) # stdout: just the path, easy to capture
228
+ print(out) # stdout: just the path, easy to capture
216
229
  print(f"saved {n} bytes from {url}", file=sys.stderr)
217
230
 
218
231
 
@@ -116,6 +116,28 @@ class TestCrashSafety(unittest.TestCase):
116
116
  cli.download = orig
117
117
 
118
118
 
119
+ class TestDefaultOutput(unittest.TestCase):
120
+ def test_default_is_in_tempdir_not_cwd(self):
121
+ import tempfile
122
+ p = cli.default_output("png")
123
+ self.assertTrue(p.startswith(tempfile.gettempdir()))
124
+ self.assertTrue(p.endswith(".png"))
125
+ # cleanup the empty file mkstemp created
126
+ try:
127
+ os.remove(p)
128
+ except OSError:
129
+ pass
130
+
131
+ def test_default_paths_are_unique(self):
132
+ a, b = cli.default_output("png"), cli.default_output("png")
133
+ self.assertNotEqual(a, b)
134
+ for p in (a, b):
135
+ try:
136
+ os.remove(p)
137
+ except OSError:
138
+ pass
139
+
140
+
119
141
  class TestNewCommands(unittest.TestCase):
120
142
  def test_version_flag_prints_and_exits(self):
121
143
  buf = io.StringIO()
File without changes
File without changes