Category Archives: workflow

Mac workflow: Tagged bookmarks

OpenMeta tagging felfedezése óta használom OS X alatt a tageket (btw OpenMeta tagek: OS X 10.9 alatt bevezetett kMDItemOMUserTags tagekké konvertálására itt ez a csodás script). A 10.9 megjelenése óta várom, hogy majd csak belekerül a Safari bookmarkok mellé is a tagging lehetősége – aztán egy nap meguntam a várakozást és csináltam magamnak egy scriptet a probléma megoldására:

set defaultPath to "SYSTEM:Users:fns:Dropbox:URL" as alias
tell application "Safari"
	set theName to name of front document
	set theURL to URL of front document
end tell
set theName to replace_chars(theName, ":", " -")
tell application "Safari"
	activate
	set resultFile to (choose file name with prompt "Save .webloc File" default name theName default location defaultPath) as text
end tell
set text item delimiters to ":"
set fileName to last text item of resultFile
set filePath to text 1 thru lastpos(resultFile, ":") of resultFile
tell application "Finder" to make new internet location file at filePath to theURL with properties {name:fileName}
on replace_chars(this_text, search_string, replacement_string)
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to ""
	return this_text
end replace_chars
on lastpos(textstring, thischar)
	return (length of textstring) - (offset of thischar in (reverse of text items of textstring as string))
end lastpos
Ha elindítod a scriptet, akkor az feldob egy file save requestert, amiben átírhatod a mentendő .webloc file nevét, illetve tageket definiálhatsz. Nálam az így mentett .webloc file-ok a Dropboxban tartott URL nevű folderbe kerülnek, így minden gépemre szépen szinkronizálódnak, metadatával együtt. A default mentési foldert ebben a sorban definiálhatod át:
set defaultPath to "SYSTEM:Users:fns:Dropbox:URL" as alias
A scriptet nálam egy Alfred workflow indítja, de futtathatod akár egy FastScripts keyboard shortcuttal, csinálhatsz belőle Automator service-et, vagy ahogy neked kényelmes – TIMTOWTD.]]>

Mac workflow: screenshot megosztás

Józsinál olvastam az előbb, hogy szerinte az optimális megoldás screenshot megosztásra, ha bekapcsolja a Dropbox automata képernyőfotó uploaderét, ami majd feltölt minden screenshotot a cloudba. Én ettől kifejezetten viszolygok, viszont egészen hasonló, csak picit paranoidabban kontrollált megoldást használok ugyanerre. Józsi nem szereti a 3rd party szoftvereket, így neki ez a verzió valószínűleg nem játszik, de ha te is hozzám hasonló shareware junkie vagy, akkor neked még jól jöhet az én workflow-m. Megosztásra én is a Dropboxot használom, csak épp nem hagyom neki, hogy hübele-Balázs mindent feltöltsön a felhőbe. Ehelyett létrehoztam a Dropbox folderben egy screenshots mappát, ami droptargetként kint van a dokkon és abba dobom a megosztandó screenshotot. A folderen ül egy Hazel folder rule, ami a beérkező file nevéből kitalálja, hogy mi lesz a Dropbox URL, majd azt bepakolja a Clipboardra:

set file_path to theFile as text
try
	set text item delimiters to ":"
	set file_name to last text item of file_path
	set text item delimiters to ""
on error
	set text item delimiters to ""
end try
set file_name to (do shell script "/usr/bin/php -r 'echo rawurlencode(\"" & file_name & "\");'")
set dropboxPath to "https://dl.dropboxusercontent.com/u/MYDROPBOXID/screenshots/" & file_name
set the clipboard to dropboxPath
A scriptben szereplő MYDROPBOXID szöveget a saját Dropbox ID-dre kell cserélni, hogy működjön a dolog. Ehhez elég, ha egyetlen, a Dropbox felhőben levő file URL-jét meglesed, ott van benne az ID. Én ezen túl még “kettőre zárom” a dolgot: futás után megváltoztatom a file color labelét tagjét szürkére: hazel-getdropboxlink-rule A módszer egyetlen hátránya, hogy sokszor a Hazel rule előbb készül el a clipboardba rakott URL-lel, mint ahogy a file felérne a felhőbe, így ha gyorsan osztod meg a linket, akkor előfordulhat, hogy az még nem él. Ha a Dropbox folderében levő file-okról meg lehetne tudni valahogy, hogy azok felkerültek-e már a felhőbe, akkor ez a probléma is megoldódna. Mielőtt bárki “de hát van stock Folder Acctions!”-t kiáltana, fűszerezzük meg még egy Hazel szépséggel: ha kidobnád, vagy csak archiválnád a screenshotjaidat, mert mondjuk zavar, hogy foglalja a Dropbox tárhelyed, akkor archiváltasd őket automatikusan: hazel-removeoldscreenshots-rule Ugyanezt persze meg lehetne csinálni saját tárhelyre FTP-zve is – akkor még a feltöltés-linkgyártás combo sem csúszna meg. Aki megírná ehhez a scriptet, nosza itt a comment box!-)

Update

Csak azért, hogy kiálljak a szerintem egyik leghasznosabb OS X alkalmazás mellett, olvastam Hazel doksit és megcsináltam az egészet Dropbox nélkül is. Ehhez mindössze egy FTP tárhelyre van szükséged – íme a rule: hazel-screenshot-uploader-ftp-only-rule A fenti scripthez képest természetesen csak a https://dl.dropboxusercontent.com/u/MYDROPBOXID/screenshots/ értékét kell arra a folderre változtatnod, ahova feltöltetted a képet.]]>

Mac workflow: Open source URL, v2

A probléma Leszedtél egy file-t valahonnan, a browser beletette a file metaadatai közé, hogy honnan kotortad azt elő a neten és most vissza kellene találnod a forráshoz.

A megoldás

Korábban ezt megcsináltuk Thingiverse-specifikusra, de nem tetszett, hogy a script önkényesen dönt, hogy nekem épp melyik URL kell, ezért faragtam belőle popup menüset, amivel Te választhatsz, hogy melyik metában tárolt URL-t nyissa a Safari. Lustáknak itt a bezippelt workflow, aki meg olvasgatná itt a postban a forrást az ide nézzen:
on run {input, parameters}
	set theFile to (input)
	set aFile to quoted form of POSIX path of theFile
	set theURL to (do shell script "mdls -name kMDItemWhereFroms -raw " & aFile)
	if theURL is "(null)" then -- no attribute
		set theURL to "(URL info not found)"
		set theMessage to ""
	else
		set URLs to {}
		repeat with i from 1 to the count of paragraphs of theURL
			set p to paragraph i of the theURL
			set firstQ to findFirst(p, "\"")
			set lastQ to lastOffset(p, "\"")
			if firstQ > 0 and lastQ > 0 and (lastQ - firstQ > 1) then
				copy characters (firstQ + 1) through (lastQ - 1) of p as string to q
				set end of URLs to q
			end if
		end repeat
		set selectedURL to false
		if (count of URLs) = 1 then
			set selectedURL to (item 1 of URLs)
		else if (count of URLs) > 1 then
			set selectedURL to (choose from list URLs with title "Open URL" with prompt "Select URL to open:" without multiple selections allowed)
		end if
		if (selectedURL is not false) then
			tell application "Safari"
				tell window 1
					set current tab to (make new tab with properties {URL:selectedURL as text})
				end tell
			end tell
		end if
	end if
	return input
end run
on findFirst(str, findString)
	-- HAS (http://applemods.sourceforge.net/mods/Data/String.php)
	local str, findString, len, oldTIDs
	set oldTIDs to AppleScript's text item delimiters
	try
		set str to str as string
		set AppleScript's text item delimiters to findString
		considering case
			set len to str's first text item's length
		end considering
		set AppleScript's text item delimiters to oldTIDs
		if len is str's length then
			return 0
		else
			return len + 1
		end if
	on error eMsg number eNum
		set AppleScript's text item delimiters to oldTIDs
		error "Can't findFirst: " & eMsg number eNum
	end try
end findFirst
on lastOffset(the_text, char)
	try
		set i to 1
		set last_occurrence to 0
		repeat count of the_text times
			if item i of the_text as string = char then
				set last_occurrence to i
			end if
			set i to i + 1
		end repeat
	on error
		return 0
	end try
	return last_occurrence
end lastOffset
]]>

Mac workflow: Open source URL service

erre. Ahogy töltögettem le Karácsony előtt a sok printelni való STL file-t a Thingiverse-ről, egyre többször jött elő, hogy meg kellene újra néznem valamit az STL file-t tartalmazó oldalon újra. Szerencsére OS X alatt a kMDItemWhereFroms metadata attribútumba bekerül a letöltés URL-je, amit én néha meg-meg néztem már korábban is egy vérbuta shell scripttel, ami nálam eddig így nézett ki:

#!/bin/sh
mdls -name kMDItemWhereFroms -raw "$*"
Ez egy zárójelek közé zárt comma delimited URL listát ad vissza. Nekem ebből az URL listából az utolsó kellene (a Thingiverse Amazon S3 storage-et használ, az első URL a storage-ra mutat, míg a második az eredeti Thingiverse oldalra), mégpedig minél kevesebb szüttyögéssel, azaz monjduk egy Service formájában. Némi rövid googling után dobta a gép a közel konyhakész scriptet a MacScripter oldaláról, már csak hozzá kellett ragasztani az Automator Service script számára szükséges paraméterátvételt és kész is:
property getSpecific : false -- show the specific download URL?
on run {input, parameters}
	set theFile to (input)
	set aFile to quoted form of POSIX path of theFile
	set theURL to (do shell script "mdls -name kMDItemWhereFroms -raw " & aFile)
	if theURL is "(null)" then -- no attribute
		set theURL to "(URL info not found)"
		set theMessage to ""
	else
		if getSpecific then -- get the first item (the download URL)
			set theURL to paragraph 2 of theURL
			set here to offset of "\"" in theURL
			set theURL to text (here + 1) thru -3 of theURL -- the download URL
			tell application "Finder"
				set name of theFile to theURL --I have no idea what im doing
			end tell
		else -- get the last item (the page/site URL)
			set theMessage to "page/site "
			set theURL to paragraph -2 of theURL
			set here to offset of "\"" in theURL
			set theURL to text (here + 1) thru -2 of theURL
		end if
		tell application "Safari"
			tell window 1
				set current tab to (make new tab with properties {URL:theURL})
			end tell
		end tell
	end if
	return input
end run
Ebből nagyjából két klikk az Automator workflow megalkotása, de ha ezzel bajban lennél, akkor
  • konyhakész service zippelt változata leszed innen
  • bemásol a ~/Library/Services/ folderbe, majd ott kicsomagol
]]>

Find duplicates

A probléma Szorgosan fotózunk. Idővel rákapunk arra is, hogy a fényképeinket szépen rendszerezett formában tároljuk valamelyik fotós workflow alkalmazás segítségével. A fotóink egy folder struktúrába importálódnak, példás rendben. Minden oké, amikor egyszer csak véletlenül egy nagy kupac régi képet kétszer húzunk be a libraryba – kész a baj, egy zsák fotónk lesz meg két példányban, feleslegesen. Lista kellene a duplikált file-jainkról!

A megoldás

Mielőtt alkalmazást keresnénk a feladat leküzdésére, agyalunk egy kicsit és kitaláljuk, hogy *nix-like környezetben menni fog ez külső segítség nélkül is. Két file egyezésének megállapításához pont elég, ha azok MD5 hash-e megegyezik. Írjunk hát egy scriptet, amely az egyező MD5 hash-ek alapján elkészít egy duplikált file listát:
# A script a duplikált file-okat tartalmazó foldert várja paraméterként
# és a jpg kiterjesztésű állományok egyezését vizsgálja csak.
NAME="*.jpg"
ALLFILES="/tmp/finddups.allfiles.tmp"
DUPHASHES="/tmp/finddups.duphashes.tmp"
find $1 -name "$NAME" -exec md5 {} \; | sort >$ALLFILES
find $1 -name "$NAME" -exec md5 -q {} \; |sort|uniq -d|sort -n >$DUPHASHES
while read hash
do
	cat $ALLFILES | grep $hash | grep -oE '\((.*-[0-9].jpg)\)' | sed "s/(// ; s/)//"
done <$DUPHASHES
Nézzük meg, mit csinálunk. Az első find-del kezdődő sor a célfolderben levő összes jpg file-unkból számol egy MD5 hash-t, majd a filelistát hash-estől leteszi egy file-ba. Ez a file valahogy így fog kinézni:
MD5 (./2000/05/15/20000515-0084.jpg) = 747888000b422d619a1b308346b7d81e
MD5 (./2000/05/15/20000515-0086-2.jpg) = d3a064924fb8306519475b09cb90d66b
MD5 (./2000/05/15/20000515-0086-3.jpg) = d3a064924fb8306519475b09cb90d66b
MD5 (./2000/05/15/20000515-0086.jpg) = d3a064924fb8306519475b09cb90d66b
A következő sorban mégegyszer végigmegyünk a jpg filejainkon, de csak az MD5 hash-üket kérjük, mindenféle sallang nélkül (=ezt adja az md5 -q opciója), majd a uniq binárissal csak a duplikált hash-eket szűrve (=-d opció) letesszük az összes, többször előforduló MD5 hasht egy másik file-ba. Ezután már csak végig kell rohannunk a duplikált hash-eken, kikeresni, hogy mely file-okhoz tartoznak és kilistázni azokat – ezt teszi a script végi ciklus. A ciklus közepén levő regexp arra hivatott, hogy az első körben előállított hash-es filelistából csak a filenevek jelenjenek meg – azok közül is csak azok a file-ok, amelyek neve -[0-9].jpg-re végződik. Tudom, hogy a végén levő sed (amellyel a kibányászott filenevek elől és mögül lecsippentjük a zárójeleket) ágyúval verébre kategória. Nekem sem tetszik, gusztustalan – azonban szűk egy órán át nem találtam más megoldást, ezért maradt ilyen. Commentben lehet szárnyalni, ki hogyan választaná le így shellben az egrep által elkapott első capture group-ot.]]>

Media Center Szent Grál: behódolunk a H264-nek

A probléma Mondjuk, hogy van egy zsák DVD-nk (tényleg van), adja Isten találtunk hozzájuk .SRT feliratokat is és mindezt cakkumpúder csinosított formában szeretnénk felajánlani az iTunes librarynknak népgazdasági hasznosításra (egy üveg fröccs már bennem van, elnézést a hablatyért).

A megoldás

A feladatot két részre bontjuk: előbb hagyjuk a computerünket tömegesen konvertálni, aztán majd szerzünk az eredményhez metaadatot is, végül megszólítjuk iTunes komát is. Csapjunk bele!

1. lépés: tömeges konverzió

Szóval nagyjából úgy, ahogy a fenti bagoly rajzolós HOWTO mutatja. Igaziból persze leszedünk egy HandbrakeCLI-t, bemásoljuk a /Applications mappánkba a binárist és megírjuk az alábbi scriptet:
#!/bin/sh
#
# Handbrake gyipaci
# lmdate 2010.07.05
#
# Végigmegy rekurzívan egy könytáron és megkeresi a filmcim-hu{n}.srt, filmcim-en{g}.srt feliratfile-okat,
# aztán ha igazán akarod, csinál neked soft subtitle-os m4v-ket az avi-jaidból.
#
# A script feltételezi, hogy ha csak egy, az avi file-lal megegyező nevű srt file-t talál, akkor abban magyar
# subtitle lakik.
#
convert() {
	film="$1"
	base="${film%.*}"
	srt="$base".srt
	hu="$base"-hu.srt
	hun="$base"-hun.srt
	en="$base"-en.srt
	eng="$base"-eng.srt
	srthuc=0
	srthu=""
	if [ -e "$srt" ];	then
		srthuc=1
		srthu="$srt"
	elif [ -e "$hu" ]; then
		srthuc=1
		srthu="$hu"
	elif [ -e "$hun" ]; then
		srthuc=1
		srthu="$hun"
	fi
	srtenc=0
	srten=""
	if [ -e "$en" ]; then
		srtenc=1
		srten="$en"
	elif [ -e "$eng" ]; then
		srtenc=1
		srten="$eng"
	fi
	let srtc=$srthuc+$srtenc
	srtfiles=""
	srtcodes=""
	srtlangs=""
	case $srtc in
		0 ) ;;
		1 )
			if [ -s "$srthu" ]; then
				srtfiles="$srthu"
				srtcodes="WINDOWS-1250"
				srtlangs="hun"
			else
				srtfiles="$srten"
				srtcodes="ISO-8859-1"
				srtlangs="eng"
			fi
			;;
		2 )
			srtfiles="$srthu","$srten"
			srtcodes="WINDOWS-1250,ISO-8859-1"
			srtlangs="hun,eng"
			;;
	esac
	if [ $srtc -ne 0 ]; then
		echo Found $srtc subtitles:
		echo "$srtfiles"
		echo "$srtcodes"
		echo "$srtlangs"
	else
		echo No subtitles found.
	fi
	options="-e x264 -q 20.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:b-pyramid=none:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500 -C 8"
	case $srtc in
		0 )
			# ha felirat nélkül is konvertálnál
			echo "" | $hbcli -v -i "$film" -o "$2" $options
			;;
		1 )
			# ha konvertálnád a home videód akkor is, ha csak a default magyar felirat van meg hozzá
			echo "" | $hbcli -v -i "$film" -o "$2" $options --srt-file "$srtfiles" --srt-codeset "$srtcodes" --srt-lang "$srtlangs"
			;;
		2 )
			# ha konvertálnád a home videód mind az angol, mind a magyar felirat birtokában a kétnyelvű családod számára
			echo "" | $hbcli -v -i "$film" -o "$2" $options --srt-file "$srtfiles" --srt-codeset "$srtcodes" --srt-lang "$srtlangs"
		 ;;
	esac
	return
}
hbcli=/Applications/HandBrakeCLI
source_dir="."
input_file_type="avi"
output_file_type="m4v"
echo "# Using HandBrakeCLI at "$hbcli
echo "# Using source directory "$source_dir
echo "# Converting "$input_file_type" to "$output_file_type
# Convert from one file to another
convert() {
   # The beginning part, echo "" | , is really important.  Without that, HandBrake exits the while loop.
   echo "" | $hbcli -i "$1" -o "$2" --preset="AppleTV 2" -C 8;
}
# Find the files and pipe the results into the read command.  The read command properly handles spaces in directories and files names.
find "$source_dir" -iname "*.$input_file_type" | while read in_file
do
        echo "Processing…"
   echo ">Input  "$in_file
   # Replace the file type
   out_file=$(echo $in_file|sed "s/\(.*\.\)$input_file_type/\1$output_file_type/g")
   echo ">Output "$out_file
   # Convert the file
   convert "$in_file" "$out_file"
   if [ $? != 0 ]
        then
            echo "$in_file had problems" >> handbrake-errors.log
        fi
   echo ">Finished "$out_file "\n\n"
done
echo "DONE CONVERTING FILES"
A sctiptünkben az options= kezdetű sorban a -C utáni számot kicseréljük a rendelkezésünkre álló CPU magok számára. Egy folderbe bepakoljuk az eddig bután .avi formában tárolt filmjeinket / sorozatainkat, melléjük tesszük az .srt file-okat (ha ezt nem értjük, elolvassuk a scriptet, nem csak nyakló nélkül mentjük). Ha ez kész, nyitunk egy shellt, bemászunk a filmek könyvtárába és elindítjuk a scriptünket, majd a végén örülünk a sok szép új m4v file-nak.

2. lépés: metázunk

Az előbb lett sok szép mv4 file-unk – ezekbe kell nekünk proper metadata. Ehhez vásároljuk meg a Mac App Storeból az iDentify alkalmazást, esetleg szedjük le a trialt innen. Az iDentifybe bedobáljuk az m4v file-jainkat, ő meg szépen feltaggeli őket. Ha ezt mégsem teszi meg magától, akkor nagy eséllyel nem tudott kitalálni szerencsétlen semmi kézzelfoghatót a filenévből. Ilyenkor forduljunk az IMDB-hez bizalommal: keressük ki a film / sorozat IMDB oldalát és adjuk meg az iDentifynek az IMDB által használt azonosítót.

3. lépés: iTunes etetés

A drága megalomán média alkalmazásunk minden valószínűség szerint a ~/Music/iTunes mappában tárolja a cuccait. Ebben a folderben keressük meg az iTunes Media/Automatically Add to iTunes könyvtárat és dobáljuk bele vadul az előbb legyártott, majd gondosan feltaggelt m4v állományainkat. Az iTunes észreveszi az új jövevényeket, belenéz a metaadatokba és szépen a helyére pakolja a cuccost. Innentől kezdve pedig már csak egy iTunes Home Sharing bekapcsolás és egy Apple TV dobozka kell ahhoz, hogy a nappaliban molesztáljuk a csodaszép videós médiatárunkat.]]>

Workflow: iOS Webapp startup/icon image generator

A probléma Designer véna híján kitaláljuk, hogy csinálunk egy darab szép nagy image-et, amiből mondjuk középre rendezve n féle méretet kellene legyártani, hogy a webalkalmazásunk mindenféle iOS eszközt kiszolgáljon ikonnal, illetve startup screen grafikával.

A megoldás

Először is előkotrunk a neten egy HOWTO-t, ami elmagyarázza, hogy mi is kell mindehhez webalkalmazásunk HTML head szekciójába:
<!-- iOS webapp icons -->
<link rel="apple-touch-icon" href="touch-icon-iphone.png" />
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" />
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone4.png" />
<link rel="apple-touch-icon" sizes="144x144" href="apple-touch-icon-144x144.png">
<!-- iOS webapp startup images -->
<!-- iPhone -->
<link rel="apple-touch-startup-image"
		 media="(device-width: 320px)"
		 href="/startup.png">
<!-- iPhone (Retina) -->
<link rel="apple-touch-startup-image"
			media="(device-width: 320px) and (-webkit-device-pixel-ratio: 2)"
			href="apple-touch-startup-image-640x920.png">
<!-- iPad (portrait) -->
<link rel="apple-touch-startup-image"
      media="(device-width: 768px)
         and (orientation: portrait)"
      href="apple-touch-startup-image-768x1004.png">
<!-- iPad (landscape) -->
<link rel="apple-touch-startup-image"
      media="(device-width: 768px)
         and (orientation: landscape)"
      href="apple-touch-startup-image-748x1024.png">
<!-- iPad (Retina, portrait) -->
<link rel="apple-touch-startup-image"
      media="(device-width: 768px)
         and (orientation: portrait)
         and (-webkit-device-pixel-ratio: 2)"
      href="apple-touch-startup-image-1536x2008.png">
<!-- iPad (Retina, landscape) -->
<link rel="apple-touch-startup-image"
      media="(device-width: 768px)
         and (orientation: landscape)
         and (-webkit-device-pixel-ratio: 2)"
      href="apple-touch-startup-image-1496x2048.png">
Ha ez megvan, csak elő kell állítani a sokféle méretű képet – ehhez vadásszunk le egy ImageMagick-et innen. Az ImageMagick felmegy MacPortsból is, de felpakolhatjuk kézzel is – ez utóbbi korrektül le van írva az előbb említett linken, de gyors kiteszem ide is: Csomagoljuk ki és csináljunk egy symlinket az általa létrehozott folderre:
mkdir ~/bin
cd ~/bin
tar xzvf ~/Downloads/ImageMagick-x86_64-apple-darwin11.3.0.tar.gz
ln -s ~/bin/ImageMagick-6.7.5 ~/bin/ImageMagick
Tegyük bele ezeket a ~/.bash_profile scriptünkbe:
# <imageMagick>
export MAGICK_HOME="$HOME/ImageMagick"
export PATH="$MAGICK_HOME/bin:$PATH"
export DYLD_LIBRARY_PATH="$MAGICK_HOME/lib/"
# </imageMagick>
Élesítsük is mindjárt:
source ~/.bash_profile
Majd írjuk meg a kép konvertálásához szükséges ImageMagickot molesztáló scriptünket (jól bekommenteztem, hátha valaha jól jön még mintának, ha Bash-ban kívánnál tömbökkel szívni):
#!/bin/sh
# createiOSWebappImages.sh by fns@fns.hu
# created 2012.06.03
# lmdate 2012.06.03
function createImages() {
	ext=".png" # default source & target extension
	args=( "$@" ) # all the paameters in an array
	ac=${#args[@]} # parameter array length
	p=${args[0]} # basePath: 1st parameter
	bf=$p/${args[1]}$ext # baseFile: 2nd parameter
	f=${args[2]} # iconFile: 3rd parameter
	for (( i=3; i<$ac; i++ )) # first 3 parameters were not the member of our resizer array so start from 3rd one
	do
		str=${args[$i]} #get array element
		len=${#str} #get length of string
		xpos=`echo "$str" | sed -n "s/[x].*//p" | wc -c` # get "x" pos within string
		w=${str:0:(xpos-1)} #substr
		h=${str:(xpos):(len-xpos)} #substr
		f2="$p/$f$str".png
		echo "Resizing image; source = $bf new_size = $str target = $f2"
		convert $bf -resize $str -gravity center -extent $str $f2
	done
} # createImages()
basePath="." # location of source & target files
baseFile="ios-webapp-baseimage" # source file
iconFile="apple-touch-icon" # target file prefix
iconSizes=( 57x57 72x72 114x114 144x144 ) # target file sizes in an array
startupFile="apple-touch-startup-image" # target file prefix
startupSizes=( 320x460 640x920 768x1004 768x1024 1536x2008 1496x2048 ) # target file sizes in an array
createImages $basePath $baseFile $iconFile "${iconSizes[@]}"
createImages $basePath $baseFile $startupFile "${startupSizes[@]}"
Végül futtassuk le és a generált képeket fogyasszuk egészséggel!]]>

Mac workflow: memory dump, avagy mentsük ami menthető

Mac Memory Reader nevű binárist használtam – egyértelmű kis célszerszám, sokat nem kérdez, csak dumpol és sanyi. A szöveget fds cimborám által is nagyra tartott Hex Fiend segített előkeresni. Ettől tovább nem is kell ragozni a történetet. Ha esett meg már veled hasonló baj, szedd most le a Mac Memory Readert, telepítsd fel, hogy amikor legközelebb ér ilyen baleset, minél kevésbé koszold be a dumpolandó memóriát.]]>

Mac workflow: a supporter fegyvere az embeddelő userek ellen

A probléma A gonosz user küld nekünk egy hibaüzenet screenshotot, jó esetben csak egy, rosszabb esetben több, általában Office dokumentumban egymásba ágyazva (jött már olyan, hogy a szép fejléces (!) PowerPointba ágyazott debug screenshot csini Word dokumentumba gyógyítva, szép veretes picture frame-mel). Megkapom, ránézek és máris nem kell lemennem evezni, hogy 150-re szökjön a pulzus: user-embeddelt-hibauzenete

A megoldás

Azért jó ideje már nem szökik. Egyfelől van nekem szép \screenshot fedőnevű TextExpander shortcutom, ami ilyet csinál azonnal a válaszmailbe:
Képernyőfotók küldése Windows alatt a legegyszerűbb módon
1. Tegyük aktívvá a fotózandó ablakot (egyszerűen rá kell csak kattintani).
2. Nyomjuk meg az Alt+Print Screen billentyűkombinációt — a fotó az aktív ablakról a vágólapra kerül.
3. Indítsuk el a levelező programunkat, kezdjünk el egy új levelet.
4. Kattintsunk a levél törzsébe, és oda illesszük be a vágólap tartalmát a Control+V billentyűkombinációval.
5. Címezzük meg a levelet és küldjük el!
Másrészt nem lennék címzetes shareware junkie lovag, ha ne tartanék erre fent egy appot. Az app neve File Juicer. A kis 13 EUR-ba kerülő shareware alkalmazás az univerzális kicsomagoló – rengetegszer behozta már az árát nekem. Számos formátumot képes atomjaira szedni, továbbá nagy segítség tud lenni, ha memóriakártyáról kell visszahozni törölt adatot. A File Juicer kis ronda ikonnal rendelkezik, valamint az UI sem egy díjnyertes csődör: file-juicer-UI Az ablak bal oldalán található drop target boxba, vagy az alkalmazás dokkon levő ikonjára kell dobnod a gonosz felhasználó által küldött dokumentumot, amit az app szétszed, ahogy illik: file-juicer-result A File Juicer természetesen AppleScriptelhető, így semeddig nem tart egy Service-t gyártani hozzá, ami jobb clickre indítja a konverziót. Minden embeddelő userellenséggel találkozó Mac OS X usernek kötelező fegyver ez a kis gyöngyszem. Update: Józsi párhuzamos postja a témában erre. ]]>

Mac workflow: fordító service

Preface: a workflow Google API-t használ, így feltételezem, hogy rendelkezel a használatához szükséges Google accounttal, továbbá Growl felhasználó vagy. Ha nincs Google accountod és nem is akarsz gyártani magadnak, illetve a Growl-tól is kiver a víz, akkor ez a leírás számodra nem nyújt explicit megoldást. Update: fds Mester hatására kigyomláltam a gusztustalan urlencode függvényt és az amúgyis nagyon okos curl binárisra róttam ezt a terhet.

A probléma

Idegen szóval / kifejezéssel találkozunk a computeren olvasás közben, amire a gyári Dictionary.app-ba integrált szótárunk nem ad fordítást.

A megoldás

Van a Google-nek jóféle online translation API-ja, amit megkérhetünk szépen, hogy fordítson nekünk. Az OS X nagy varázslata a rendszer szintű AppleScript támogatás és az Automator fedőnevű makrózó csoda – őket szólítjuk most csatába. Első körben ellátogatunk a Google Translate API oldalára és végigolvassuk a doksit. A dokumentáció szépen elmagyarázza, hogy Google-ék egy ilyen GET requestre adnak értelmes választ:
https://www.googleapis.com/language/translate/v2?parameters
A HTTPS request felparaméterezve így néz ki:
https://www.googleapis.com/language/translate/v2?key=INSERT-YOUR-KEY&q=hello%20world&source=en&target=hu
Miután ezt megtudtuk, a doksiban leírtak szerint látogassunk el a Google APIs Console oldalra, készítsünk egy új Translate projectet és már meg is szereztük a Translate API híváshoz szükséges kulcsot. Megvan a kulcs, csinálhatunk jó kis Service-et! Elindítod az Automator alkalmazást, majd kiválasztod a Service típusú template-et: A megjelenő editorban a Library/Utilities szekcióból kikeresed a Run AppleScript actiont és behúzod a munkaterületre: Ezután már csak bepakolod a script helyére azt, amint én hajnalban már kiszenvedtem, beteszed a set myKey to "PUT_YOUR_GOOGLE_API_KEY_HERE" sorba a te saját Google Translate API kulcsod és lemented a file-t Translate néven. Ha mindent jól csináltál, akkor megjelent egy Translate nevű service a gépeden, ami úgy működik, hogy egy tetszőleges alkalmazásban kijelölt szövegen jobb clicket nyomva, majd a Services menü Translate opcióját kiválasztva a script megküldi a Google Translate APInak a kijelölt szöveget és a visszakapott fordítást megjeleníti neked egy Growl notification buborékban, valahogy így: [video mp4="/fns.hu/video/mac-workflow-translate-service.mov" width="500" options="controls"] Végül nézzük meg a scriptet egyben, úgy, ahogy magamnak implementáltam:
(*
	Translate
	by Gabor PENOFF (//fns.pappito.com)
	release 20110208_092849
	About:
	Requirements:
	- insert your own Google API key
	- install Growl from http://growl.info to get non-modal notification dialogs
	Usage:
	- select some text and run the service
	That's all.
*)
on run {input, parameters}
	set srcText to input as text
	set srcLang to "en" -- source language
	set tgtLang to "hu" -- target language
	set myKey to "AIzaSyCI-2oapEkMpRFfd6Ltv4HkZhf1Zq-VU9o"
	set myScriptID to "Translate" -- ID for Growl display
	set myTranslation to do shell script "/usr/bin/curl -G --data-urlencode q=" & quoted form of srcText & " --data-urlencode key=" & quoted form of myKey & " --data-urlencode source=" & quoted form of srcLang & " --data-urlencode target=" & quoted form of tgtLang & space & quoted form of "https://www.googleapis.com/language/translate/v2"
	if myTranslation = "" then
		tell me to notifyWithGrowl(myScriptID, "ERROR")
		return
	end if
	-- get rid of JSON (ugly but works)
	set myPrefix to "translatedText\": \""
	set myPostfix to "\""
	set myStartPos to (offset of myPrefix in myTranslation) + (length of myPrefix)
	set myText to text myStartPos thru -1 of myTranslation
	set myEndPos to (offset of myPostfix in myText)
	set myText to text 1 thru (myEndPos - 1) of myText
	tell me to notifyWithGrowl(myScriptID, myText)
	return "" -- myText
end run
-- GrowlCheck:
on growlInstalled()
	try
		do shell script "ls /Library/PreferencePanes/Growl.prefPane/"
		return true
	on error
		return false
	end try
end growlInstalled
-- Growl notifier:
on notifyWithGrowl(myApp, myText)
	set myIconApp to "Safari"
	set notificationID to myApp & ".default"
	if growlInstalled() then
		tell application "GrowlHelperApp"
			-- list of notification types
			set the ANL to {notificationID}
			-- list of enabled notifications
			set the DNL to {notificationID}
			-- register script
			register as application myApp all notifications ANL default notifications DNL icon of application myIconApp
			-- send notification
			notify with name notificationID title myApp description myText application name myApp
		end tell
	else
		-- skip alert if no Growl installed
		--display alert "Growl is not installed"
	end if
end notifyWithGrowl
Türelmetleneknek / elfoglaltaknak / lustáknak az egész service szedhető innen – persze még ebben is be kell pakolnod a saját magad Google API kulcsát, hogy működjön.]]>