├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ └── feature_suggestion.yml
├── LICENSE
├── README.md
└── Workflow
├── icon.png
├── images
└── about
│ ├── tinypng.png
│ └── ua.png
└── info.plist
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: File a bug report
3 | body:
4 | - type: input
5 | attributes:
6 | label: Workflow version
7 | description: Open the Workflow in Alfred Preferences and find it at the top, near the description
8 | validations:
9 | required: true
10 | - type: input
11 | attributes:
12 | label: Alfred version
13 | description: In the top left corner of Alfred Preferences → General
14 | validations:
15 | required: true
16 | - type: input
17 | attributes:
18 | label: macOS version
19 | description: Click on the menubar → About This Mac
20 | validations:
21 | required: true
22 | - type: textarea
23 | attributes:
24 | label: Debugger output
25 | description: Perform the failing action with [the debugger](https://www.alfredapp.com/help/workflows/advanced/debugger/) open
26 | render: alfred_debugger
27 | validations:
28 | required: true
29 | - type: textarea
30 | attributes:
31 | label: More details
32 | description: Explain what you did, what happened, and what you expected to happen
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_suggestion.yml:
--------------------------------------------------------------------------------
1 | name: Feature Suggestion
2 | description: Suggest a new feature
3 | body:
4 | - type: textarea
5 | attributes:
6 | label: Feature details
7 | description: Explain the feature idea
8 | validations:
9 | required: true
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2021, Running with Crayons Ltd
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #
TinyPNG Alfred Workflow
2 |
3 | Compress images via TinyPNG
4 |
5 | [⤓ Install on the Alfred Gallery](https://alfred.app/workflows/alfredapp/tinypng)
6 |
7 | ## Usage
8 |
9 | Compress PNG, JPEG, and WebP images with [TinyPNG](https://tinypng.com/) via the [Universal Action](https://www.alfredapp.com/help/features/universal-actions/).
10 |
11 | 
12 |
13 | Alternatively, find images with the `tinypng` keyword.
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/Workflow/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alfredapp/tinypng-workflow/8a5be899cc8c79cc6eef0011e750781b28859061/Workflow/icon.png
--------------------------------------------------------------------------------
/Workflow/images/about/tinypng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alfredapp/tinypng-workflow/8a5be899cc8c79cc6eef0011e750781b28859061/Workflow/images/about/tinypng.png
--------------------------------------------------------------------------------
/Workflow/images/about/ua.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alfredapp/tinypng-workflow/8a5be899cc8c79cc6eef0011e750781b28859061/Workflow/images/about/ua.png
--------------------------------------------------------------------------------
/Workflow/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | com.alfredapp.vitor.tinypng
7 | connections
8 |
9 | 392049EC-35AB-4C54-8A20-5565FBF67B32
10 |
11 |
12 | destinationuid
13 | F2C7428D-06C2-4B70-8C70-8348AE71B137
14 | modifiers
15 | 0
16 | modifiersubtext
17 |
18 | vitoclose
19 |
20 |
21 |
22 | 72DE7DEE-B771-41EA-9A7C-F10F4F7A5DC5
23 |
24 | 7EA1CA9C-97FC-4B89-999A-7CFE3D8CB0AE
25 |
26 |
27 | destinationuid
28 | F2C7428D-06C2-4B70-8C70-8348AE71B137
29 | modifiers
30 | 0
31 | modifiersubtext
32 |
33 | vitoclose
34 |
35 |
36 |
37 | 8F44CFA0-9821-4998-B57A-CBD196BD069B
38 |
39 |
40 | destinationuid
41 | F2C7428D-06C2-4B70-8C70-8348AE71B137
42 | modifiers
43 | 0
44 | modifiersubtext
45 |
46 | vitoclose
47 |
48 |
49 |
50 | 9EDA38AD-8C38-42CA-A270-CFE7AEC0655C
51 |
52 |
53 | destinationuid
54 | 72DE7DEE-B771-41EA-9A7C-F10F4F7A5DC5
55 | modifiers
56 | 0
57 | modifiersubtext
58 |
59 | vitoclose
60 |
61 |
62 |
63 | destinationuid
64 | C22E0CBD-0683-4E3A-80E5-6532D8E5440E
65 | modifiers
66 | 0
67 | modifiersubtext
68 |
69 | vitoclose
70 |
71 |
72 |
73 | C22E0CBD-0683-4E3A-80E5-6532D8E5440E
74 |
75 |
76 | destinationuid
77 | 4D6432C7-2943-4DB6-A25F-B0AC57D3C6F2
78 | modifiers
79 | 0
80 | modifiersubtext
81 |
82 | sourceoutputuid
83 | 2402FAA7-E693-486D-84EA-BF27BF8E4AFD
84 | vitoclose
85 |
86 |
87 |
88 | destinationuid
89 | 6D56D157-3EBC-41F6-A030-1C9A9E4490DF
90 | modifiers
91 | 0
92 | modifiersubtext
93 |
94 | vitoclose
95 |
96 |
97 |
98 | CB42BCC1-C05C-4B82-821E-BF371D852F7A
99 |
100 |
101 | destinationuid
102 | 8F44CFA0-9821-4998-B57A-CBD196BD069B
103 | modifiers
104 | 0
105 | modifiersubtext
106 |
107 | vitoclose
108 |
109 |
110 |
111 | F2C7428D-06C2-4B70-8C70-8348AE71B137
112 |
113 |
114 | destinationuid
115 | 9EDA38AD-8C38-42CA-A270-CFE7AEC0655C
116 | modifiers
117 | 0
118 | modifiersubtext
119 |
120 | vitoclose
121 |
122 |
123 |
124 | FD60CC76-3DD5-45D7-A184-5A5580E0790F
125 |
126 |
127 | destinationuid
128 | F2C7428D-06C2-4B70-8C70-8348AE71B137
129 | modifiers
130 | 0
131 | modifiersubtext
132 |
133 | vitoclose
134 |
135 |
136 |
137 |
138 | createdby
139 | Vítor Galvão
140 | description
141 | Compress images via TinyPNG
142 | disabled
143 |
144 | name
145 | TinyPNG
146 | objects
147 |
148 |
149 | config
150 |
151 | acceptsmulti
152 | 1
153 | filetypes
154 |
155 | org.webmproject.webp
156 | public.jpeg
157 | public.png
158 |
159 | name
160 | TinyPNG Compression
161 |
162 | type
163 | alfred.workflow.trigger.action
164 | uid
165 | 7EA1CA9C-97FC-4B89-999A-7CFE3D8CB0AE
166 | version
167 | 1
168 |
169 |
170 | config
171 |
172 | concurrently
173 |
174 | escaping
175 | 102
176 | script
177 | # Constants
178 | readonly backup_dir="${backup_originals}/$(date +'%Y.%m.%d.%H.%M.%S')"
179 |
180 | # Helpers
181 | function get_json_key {
182 | local -r json="${1}" # JSON string
183 | local -r key="${2}" # Of the form ['first']['second'] or .first.second
184 |
185 | local -r result="$(/usr/bin/osascript -l 'JavaScript' -e "function run(argv) { return JSON.parse(argv[0])${key} }" "${json}")"
186 |
187 | [[ -n "${key}" && -n "${result}" ]] || return 1 # If no valid result
188 |
189 | echo -n "${result}"
190 | }
191 |
192 | function state {
193 | /usr/bin/osascript -l JavaScript -e "function run(argv) {
194 | return JSON.stringify({ alfredworkflow: { variables: {
195 | success: argv[0] === 'success',
196 | message: argv[1]
197 | }}})
198 | }" "${1}" "${2}"
199 | }
200 |
201 | function error {
202 | echo "${1}" >&2 # For Alfred's debugger
203 | state 'failure' "${1}" # For the notification and sound
204 | exit 1
205 | }
206 |
207 | # Main
208 | # Abort if backups are desirable but cannot create directory
209 | if [[ -n "${backup_originals}" ]] && ! /bin/mkdir -p "${backup_dir}"; then
210 | error "Could not create backups directory at ${backup_originals}!"
211 | fi
212 |
213 | # Loop over images
214 | for image in "${@}"; do
215 | json_response="$(/usr/bin/curl --silent --user api:"${api_key}" --data-binary @"${image}" -i 'https://api.tinify.com/shrink' | /usr/bin/tail -1)"
216 |
217 | # On failed connection
218 | if [[ -z "${json_response}" ]]; then
219 | error 'Unable to connect to TinyPNG'
220 | fi
221 |
222 | # On error
223 | if [[ -n "$(get_json_key "${json_response}" '.error')" ]]; then
224 | error "$(get_json_key "${json_response}" '.message')"
225 | fi
226 |
227 | # Backup image
228 | if [[ -d "${backup_dir}" ]]; then
229 | /bin/cp -p "${image}" "${backup_dir}"
230 | fi
231 |
232 | # Save result
233 | compressed_url="$(get_json_key "${json_response}" '.output.url')"
234 | /usr/bin/curl --silent "${compressed_url}" --output "${image}"
235 | done
236 |
237 | state 'success' 'Finished compressing'
238 | scriptargtype
239 | 1
240 | scriptfile
241 |
242 | type
243 | 11
244 |
245 | type
246 | alfred.workflow.action.script
247 | uid
248 | F2C7428D-06C2-4B70-8C70-8348AE71B137
249 | version
250 | 2
251 |
252 |
253 | config
254 |
255 | anchorfields
256 |
257 | argumenttrimmode
258 | 0
259 | argumenttype
260 | 0
261 | daterange
262 | 0
263 | fields
264 |
265 |
266 | field
267 | kMDItemDisplayName
268 | not
269 |
270 | split
271 |
272 | value
273 | {query}
274 | words
275 |
276 |
277 |
278 | field
279 | kMDItemAlternateNames
280 | not
281 |
282 | split
283 |
284 | value
285 | {query}
286 | words
287 |
288 |
289 |
290 | field
291 | kMDItemFinderComment
292 | not
293 |
294 | split
295 |
296 | value
297 | {query}
298 | words
299 |
300 |
301 |
302 | includesystem
303 |
304 | keyword
305 | {var:search_keyword}
306 | limit
307 | 0
308 | runningsubtext
309 |
310 | scopes
311 |
312 | sortmode
313 | 0
314 | subtext
315 | Filter for images to compress
316 | title
317 | TinyPNG Compression
318 | types
319 |
320 | org.webmproject.webp
321 | public.jpeg
322 | public.png
323 |
324 | withspace
325 |
326 |
327 | type
328 | alfred.workflow.input.filefilter
329 | uid
330 | 392049EC-35AB-4C54-8A20-5565FBF67B32
331 | version
332 | 2
333 |
334 |
335 | config
336 |
337 | lastpathcomponent
338 |
339 | onlyshowifquerypopulated
340 |
341 | removeextension
342 |
343 | text
344 | {var:message}
345 | title
346 | TinyPNG
347 |
348 | type
349 | alfred.workflow.output.notification
350 | uid
351 | 72DE7DEE-B771-41EA-9A7C-F10F4F7A5DC5
352 | version
353 | 1
354 |
355 |
356 | config
357 |
358 | conditions
359 |
360 |
361 | inputstring
362 | {var:notify}
363 | matchcasesensitive
364 |
365 | matchmode
366 | 0
367 | matchstring
368 | false
369 | outputlabel
370 | Do not notify
371 | uid
372 | 3052F81B-0ECE-4815-AFAE-DCDD42361205
373 |
374 |
375 | elselabel
376 | Notify
377 | hideelse
378 |
379 |
380 | type
381 | alfred.workflow.utility.conditional
382 | uid
383 | 9EDA38AD-8C38-42CA-A270-CFE7AEC0655C
384 | version
385 | 1
386 |
387 |
388 | config
389 |
390 | soundname
391 | Glass
392 | systemsound
393 |
394 |
395 | type
396 | alfred.workflow.output.playsound
397 | uid
398 | 4D6432C7-2943-4DB6-A25F-B0AC57D3C6F2
399 | version
400 | 1
401 |
402 |
403 | config
404 |
405 | availableviaurlhandler
406 |
407 | triggerid
408 | compress
409 |
410 | type
411 | alfred.workflow.trigger.external
412 | uid
413 | FD60CC76-3DD5-45D7-A184-5A5580E0790F
414 | version
415 | 1
416 |
417 |
418 | config
419 |
420 | conditions
421 |
422 |
423 | inputstring
424 | {var:success}
425 | matchcasesensitive
426 |
427 | matchmode
428 | 5
429 | matchstring
430 |
431 | outputlabel
432 | Success
433 | uid
434 | 2402FAA7-E693-486D-84EA-BF27BF8E4AFD
435 |
436 |
437 | elselabel
438 | Error
439 | hideelse
440 |
441 |
442 | type
443 | alfred.workflow.utility.conditional
444 | uid
445 | C22E0CBD-0683-4E3A-80E5-6532D8E5440E
446 | version
447 | 1
448 |
449 |
450 | config
451 |
452 | availableviaurlhandler
453 |
454 | triggerid
455 | silent_compress
456 |
457 | type
458 | alfred.workflow.trigger.external
459 | uid
460 | CB42BCC1-C05C-4B82-821E-BF371D852F7A
461 | version
462 | 1
463 |
464 |
465 | config
466 |
467 | soundname
468 | Basso
469 | systemsound
470 |
471 |
472 | type
473 | alfred.workflow.output.playsound
474 | uid
475 | 6D56D157-3EBC-41F6-A030-1C9A9E4490DF
476 | version
477 | 1
478 |
479 |
480 | config
481 |
482 | argument
483 | {query}
484 | passthroughargument
485 |
486 | variables
487 |
488 | notify
489 | false
490 |
491 |
492 | type
493 | alfred.workflow.utility.argument
494 | uid
495 | 8F44CFA0-9821-4998-B57A-CBD196BD069B
496 | version
497 | 1
498 |
499 |
500 | readme
501 | ## Usage
502 |
503 | Compress PNG, JPEG, and WebP images with [TinyPNG](https://tinypng.com/) via the [Universal Action](https://www.alfredapp.com/help/features/universal-actions/).
504 |
505 | 
506 |
507 | Alternatively, find images with the `tinypng` keyword.
508 |
509 | 
510 | uidata
511 |
512 | 392049EC-35AB-4C54-8A20-5565FBF67B32
513 |
514 | xpos
515 | 35
516 | ypos
517 | 190
518 |
519 | 4D6432C7-2943-4DB6-A25F-B0AC57D3C6F2
520 |
521 | xpos
522 | 670
523 | ypos
524 | 320
525 |
526 | 6D56D157-3EBC-41F6-A030-1C9A9E4490DF
527 |
528 | xpos
529 | 670
530 | ypos
531 | 455
532 |
533 | 72DE7DEE-B771-41EA-9A7C-F10F4F7A5DC5
534 |
535 | xpos
536 | 670
537 | ypos
538 | 190
539 |
540 | 7EA1CA9C-97FC-4B89-999A-7CFE3D8CB0AE
541 |
542 | xpos
543 | 35
544 | ypos
545 | 40
546 |
547 | 8F44CFA0-9821-4998-B57A-CBD196BD069B
548 |
549 | xpos
550 | 195
551 | ypos
552 | 480
553 |
554 | 9EDA38AD-8C38-42CA-A270-CFE7AEC0655C
555 |
556 | xpos
557 | 400
558 | ypos
559 | 195
560 |
561 | C22E0CBD-0683-4E3A-80E5-6532D8E5440E
562 |
563 | xpos
564 | 550
565 | ypos
566 | 355
567 |
568 | CB42BCC1-C05C-4B82-821E-BF371D852F7A
569 |
570 | note
571 | Compress but do not show notification
572 | xpos
573 | 35
574 | ypos
575 | 450
576 |
577 | F2C7428D-06C2-4B70-8C70-8348AE71B137
578 |
579 | xpos
580 | 235
581 | ypos
582 | 40
583 |
584 | FD60CC76-3DD5-45D7-A184-5A5580E0790F
585 |
586 | xpos
587 | 35
588 | ypos
589 | 320
590 |
591 |
592 | userconfigurationconfig
593 |
594 |
595 | config
596 |
597 | default
598 | tinypng
599 | placeholder
600 |
601 | required
602 |
603 | trim
604 |
605 |
606 | description
607 |
608 | label
609 | Search Keyword
610 | type
611 | textfield
612 | variable
613 | search_keyword
614 |
615 |
616 | config
617 |
618 | default
619 | /tmp/com.alfredapp.vitor.tinypng.backups
620 | filtermode
621 | 1
622 | placeholder
623 |
624 | required
625 |
626 |
627 | description
628 | The default backup location is deleted when macOS restarts.
629 | label
630 | Backup Originals
631 | type
632 | filepicker
633 | variable
634 | backup_originals
635 |
636 |
637 | config
638 |
639 | default
640 |
641 | placeholder
642 |
643 | required
644 |
645 | trim
646 |
647 |
648 | description
649 | Request one at https://tinypng.com/developers
650 | label
651 | API Key
652 | type
653 | textfield
654 | variable
655 | api_key
656 |
657 |
658 | version
659 | 2024.2
660 | webaddress
661 | https://github.com/alfredapp/tinypng-workflow/
662 |
663 |
664 |
--------------------------------------------------------------------------------