Category Archives: AppleScript

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.]]>

Mac workflow: blogpic HOWTO

A Mac recept Hozzávalók:

  • Acorn – image editor Gus Mueller billentyűzetéből. Puritán, letisztult, szeretem.
  • JSTalk – script bridge, szintén Gustól. Segítségével a scriptelhető OS X alkalmazásokhoz JavaScriptes vagy Objective C-s stílusban írhatsz scripteket.
  • TextExpander – (akár) scriptelhető text makrózó tool, mely számos változó használatát (dátum és idő, clipboard tartalom, kép, kurzorműveletek) engedi meg.
  • WordPress FancyZoom plugin – Cabel Sasser JavaScriptben írt remeke. Ő állítja elő az oldalba pakolt img HTML tag-ekhez a zoom effektet, amikor a thumbnailre klattyolsz.
A workflow A dolog onnan indul, hogy a kívánt képet 1280×1280 max méretre cropolom, majd lementem jpg formátumban. Az így előkészített képet bedobom az Acorn-ba, majd lefuttatom a Framer fedőnevű JSTalk scriptet, aki előállít egy 500 pixel széles smallDoc.png thumbnail image-et a beledobott képből. A két képet feltöltöm a WordPressbe, majd egy TextExpander makró segítségével berámolom a postba a thumbnailhez és az alatta levő image-hez szükséges HTML kódot. Nézzük meg a JSTalk scriptet és a TextExpander snippetet, aztán jöhet a kovászos ubi receptje. Elsőként itt a script – ehhez túl sok közöm nincs, Gus csomagolta a JSTalk példák közé, nekem meg nagyon megtetszett az eredménye. Persze lehetne ez egyszer CSS3, de amíg nem, addig jó ez így is, hardcoded módon:
var acorn = [JSTalk application:"Acorn"];
// var doc = acorn.open_("/path/to/SomeImage.jpg");
var doc = [[acorn orderedDocuments] objectAtIndex:0];
// scale our image down
[doc scaleImageToWidth:492];
var image = [[[NSImage alloc] initWithData:[doc dataRepresentationOfType:"public.png"]] autorelease];
// close the doc, since we've already got the data we need.
[doc close];
var bitmap = [image bestRepresentationForDevice:nil];
var extent = NSMakeRect(0, 0, [bitmap pixelsWide], [bitmap pixelsHigh]);
var xOffset = 5;
var yOffset = 35;
var curveHeight = 15;
var imageYOffset = 10;
var whiteBorderWidth = 4;
var doubleBorderWidth = whiteBorderWidth * 2;
var newSize = NSMakeSize(extent.size.width + (whiteBorderWidth * 2),
                         extent.size.height + imageYOffset + (whiteBorderWidth * 2));
var newImage = [[[NSImage alloc] initWithSize:newSize] autorelease];
[newImage lockFocus];
[[NSGraphicsContext currentContext] saveGraphicsState];
var shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:.6]];
var shadowOffset = NSMakeSize(0, -(yOffset + 5));
[shadow setShadowOffset:shadowOffset];
[shadow setShadowBlurRadius:5];
shadow.set()
// make a curved path, at the bottom of our image.
bezierPath = NSBezierPath.bezierPath();
[bezierPath moveToPoint:NSMakePoint(xOffset, 40 + yOffset)];
[bezierPath lineToPoint:NSMakePoint(extent.size.width - (xOffset) + doubleBorderWidth, 40 + yOffset)];
[bezierPath lineToPoint:NSMakePoint(extent.size.width - (xOffset) + doubleBorderWidth, 10 + yOffset)];
[bezierPath curveToPoint:NSMakePoint(newSize.width / 2, curveHeight + yOffset)
           controlPoint1:NSMakePoint(extent.size.width - (xOffset), 10 + yOffset)
           controlPoint2:NSMakePoint(newSize.width *.75, curveHeight + yOffset)];
[bezierPath curveToPoint:NSMakePoint(xOffset, 10 + yOffset)
           controlPoint1:NSMakePoint(newSize.width *.25, curveHeight + yOffset)
           controlPoint2:NSMakePoint(xOffset, 10 + yOffset)];
[bezierPath fill];
// get rid of our shadow
[[NSGraphicsContext currentContext] restoreGraphicsState];
// draw a white border
[[NSColor whiteColor] set];
[[NSBezierPath bezierPathWithRect:NSMakeRect(0, imageYOffset, newSize.width, extent.size.height + whiteBorderWidth * 2)] fill];
// draw our gray border around the white border
[[NSColor lightGrayColor] set];
[[NSBezierPath bezierPathWithRect:NSMakeRect(.5, imageYOffset + .5 , newSize.width - 1, (extent.size.height - 1) + (whiteBorderWidth * 2))] stroke];
// NSImage takes into account dpi of the image.  So we force it's size, to avoid small images.
[image setSize: extent.size];
// draw our image
[image drawAtPoint:NSMakePoint(whiteBorderWidth, imageYOffset + whiteBorderWidth)
          fromRect:NSMakeRect(0, 0, extent.size.width, extent.size.height)
         operation:NSCompositeCopy
          fraction:1];
[newImage unlockFocus];
var smallDoc = [[acorn sharedDocumentController] newDocumentWithImageData: [newImage TIFFRepresentation]];
[[smallDoc dataRepresentationOfType:"public.png"] writeToFile:"/Users/fns/Desktop/smallDoc.png"];
[smallDoc close];
Ez pedig a TextExpander snippet:
<a href="//fns.pappito.com/files/%Y/%m/%clipboard.jpg"><img src="//fns.pappito.com/files/%Y/%m/%clipboard.png" alt="" title="%clipboard"/></a>
A TextExpander snippetnél mindössze annyi dolgom van pluszban, hogy a kép nevét a clipboardba másoljam. Ez meg OS X alatt egy Enter a filenéven, majd ⌘C és Sanyi. A kovászos ubi recept Egy 5 literes befőttes üvegbe kb. 3 kiló uborka fér. Az üveget forró vízzel kimosom, majd elfektetem, hogy könnyebb legyen bele pakolni. Az uborkák két végét levágom, hosszában 4-5-6 vágást ejtek rajtuk. Nekiállok úgy bepakolni az uborkákat, hogy függőlegesen álljanak majd az üvegben, mikor érleli őket a Nap. Egy réteg uborka után egy nagy adag kaprot teszek be az üvegbe (persze csak akkor, ha épp nem Pappitonak készül a cucc :)), majd megint ubi és ez így megy addig, amíg meg nem telik a bödön. Óvatosan felállítom az üveget, majd 2 púpos evőkanál sót teszek a tetejére. Felforralok 3-4 liter vizet és egy merőkanállal rákanalazom az uborkákra, amíg tele nem lesz az üveg. A végén egy szelet kenyeret nyomok a tetejébe, letakarom az egészet egy tányérral és megy ki a Napra, 3-4 napig. Mikor a lé már zavaros, leszedem a kenyeret, de 1-2 napot adok még neki a melegen, hadd érjen össze. ]]>

Meteo script update

itt, magyar billentyűzethez itt, a forrás meg alant (a script a ~/Pictures könyváradban létre fog hozni egy delme-meteo nevű foldert, amibe a leszippantott képeket menti. Ezt a foldert törli és létrehozza minden alkalommal újra és újra.):

(*
	Meteo
	by Gabor PENOFF (//fns.pappito.com)
	release 20100516-1002
	Requirements:
	- before run you need to Enable Access for Assistive Devices in SysPrefs/Universal Access
	- install Growl from http://growl.info to get non-modal notification dialogs
	Usage:
	- just run the script
	That's all.
*)
set myScriptID to "Meteo" -- ID for Growl display
-- set date variables:
set myYear to get text 1 thru 4 of (year of (current date) as string)
set myMonth to month of (current date) as number
if myMonth < 10 then set myMonth to "0" & myMonth as string
set myDay to day of (current date)
if myDay < 10 then set myDay to "0" & myDay as string
set myHour to hours of (current date)
if myHour < 10 then set myHour to "0" & myHour as string
set myMinute to "00"
set tmpDir to "delme-meteo"
set myFilePrefix to "delme-met-"
set tIdokepStart to "http://www.idokep.hu/arch_kep.php?kep="
set myURLs to {¬
	"http://img.koponyeg.hu/img/15napos/" & myYear & "/" & myMonth & "/1_" & myYear & "-" & myMonth & "-" & myDay & "grafikon.png|png", ¬
	"http://terkep.idokep.hu/kep.php?kep=mix|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=hoterkep2&regio=hu1680|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=felhokep2&regio=hu1680|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=szelterkep2_anim|gif", ¬
	"http://terkep.idokep.hu/kep.php?kep=szelterkep2&regio=hu1680|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=legnyomasterkep|jpg", ¬
	"http://feny.idokep.hu/kep.php?kep=csap24|jpg", ¬
	"http://feny.idokep.hu/kep.php?kep=csap1|jpg", ¬
	"http://feny.idokep.hu/kep.php?kep=aqua|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=rh|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=uv|jpg", ¬
	"http://terkep.idokep.hu/kep.php?kep=pollen0|jpg"}
set rootDir to (path to home folder as string) & "Pictures"
tell application "Finder" to set fullDir to rootDir & ":" & tmpDir -- save fullDir
set myNotification to "Downloading METEO images to " & fullDir & "..."
tell me to notifyWithGrowl(myScriptID, myNotification)
try
	tell application "Finder" to delete fullDir
end try
tell application "Finder" to make new folder at alias rootDir with properties {name:tmpDir}
-- download files:
tell application "URL Access Scripting"
	set i to 1
	repeat with myURL in myURLs
		set thisURL to (text 1 thru ((offset of "|" in myURL) - 1) of myURL)
		set thisExt to (text ((offset of "|" in myURL) + 1) thru (length of myURL) of myURL)
		set the myFile to fullDir & ":" & myFilePrefix & i & "." & thisExt
		download thisURL to file myFile replacing yes
		set i to i + 1
	end repeat
end tell
-- display images using full-featured QuickLook window:
tell application "Finder"
	activate
	open folder fullDir
	set current view of front Finder window to list view
end tell
tell application "System Events"
	key code 0 using {command down} -- cmd+a
	key code 6 using {command down, option down} -- cmd+opt+y; y is 16 for US, 6 for Hungarians :)
end tell
-- that would be the callback after QuickLook:
--tell application "Finder"
--	activate
--	set current view of front Finder window to v
--	close front Finder window
--end tell
-- display images using a very limited (dumb) QuickLook window:
--do shell script "qlmanage -p  " & (POSIX path of fullDir) & "/* >& /dev/null"
-- 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 "Preview"
	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
]]>

Plain Text QuickLook ismeretlen file-okhoz

tell application "Finder"
	copy selection to selectedItems
	if ((count of selectedItems)0) then
		repeat with selectedItem in selectedItems
			set file type of file (selectedItem as alias) to "TEXT"
			set p to quoted form of (POSIX path of (selectedItem as alias)) as string
			do shell script ("qlmanage -p " & p)
		end repeat
	end if
end tell
2. Lemented valami rövid néven úgy, hogy a File Format mezőt “Application” típusúra állítod – mehet akár a /Applications folderbe, akár bárhova máshova, amit a Spotlight lát. Ezek után ha szembejön a Finderben egy file, amit plain textként szeretnél megnézni, de annak a típusa még nem TEXT (.sub, .srt, .nfo file-ok mind ilyenek lesznek), akkor a Finderben a kérdéses file-on állva nyomsz egy ⌘Space kombinációt, hogy előbújjon a Spotlight, beírod neki villámgyorsan, hogy “ql” (vagy amilyen nevet kitaláltál) és az előbb elkészített script alkalmazásod mindjárt be is állítja TEXT típusúnak a kérdéses file-t, plusz szól a QuickLook-nak, hogy meg szeretnéd nézni. ]]>