Hammerspoon 사용해 데스크탑 자동화

Hammerspoon

Hammerspoon 은 macOS의 데스크탑 자동화를 위해 Lua scipt 를 사용하는 엔진이다. Hammerspoon을 다운받아 설치하고 에 있는 Getting Started 를 보고 바로 시작할 수 있다.

설치

최신 릴리즈를 Latest Hammerspoon 에서 다운받아 Application 폴더로 옮긴다.

그리고 Hammerspoon을 실행하면 Status bar에 나타난다.

Hammerspoon

[그림. Hammerspoon]

환경설정 / 보안 및 개인정보 에서 손쉬운 사용에 hammerspoon을 추가해 주고 활성화 한다.

Hammerspoon

[그림. 보안 및 개인정보에서 제어 허용]

Open config

Hammerspoon 메뉴에서 Open Config 를 실행하면 시스템의 .lua 확장자를 열 수 있는 텍스트 에디터가 실행된다. 이곳에 Getting Started 의 샘플 스크립을 복사해서 바로 사용해 볼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "Y", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x - 10
f.y = f.y - 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "K", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.y = f.y - 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "U", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x + 10
f.y = f.y - 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "H", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x - 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "L", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x + 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "B", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x - 10
f.y = f.y + 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "J", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.y = f.y + 10
win:setFrame(f)
end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "N", function()
local win = hs.window.focusedWindow()
local f = win:frame()

f.x = f.x + 10
f.y = f.y + 10
win:setFrame(f)
end)

init.lua 에 스크립을 작성하고 저장한 후에 Hammerspoon 메뉴에서 Reload config를 실행하고 Console… 메뉴로 스크립 활성화를 확인할 수 있다.

Window Resizing

*Cmd+Opt+Ctrl+F** 키로 윈도우를 고정된 크기로 변경할 수 있게 사용하고 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
--[[
Window Resizing
--]]

-- Full screen
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "F", function()
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()

f.x = max.x
f.y = max.y
f.w = max.w
f.h = max.h
win:setFrame(f)
end)

-- 4:3 ratio: XGA, 1280x960, SXGA+, UGA
-- Resizing: XGA 1024-768
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "F1", function()
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()

f.x = max.x
f.y = max.y
f.w = 1024
f.h = 768
win:setFrame(f)
hs.notify.new({title="Resizing...", informativeText="1024x768"}):send()
end)


-- Resize: 1280x960 (1024)
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "F2", function()
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()

f.x = max.x
f.y = max.y
f.w = 1280
f.h = 960
win:setFrame(f)

hs.notify.new({title="Resizing...", informativeText="1280x960"}):send()
end)

-- Resize: SXGA+ 1400x1050
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "F3", function()
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()

f.x = max.x
f.y = max.y
f.w = 1400
f.h = 1050
win:setFrame(f)

hs.notify.new({title="Resizing...", informativeText="1400x1050"}):send()
end)

-- Resize: 1920x1080
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "F4", function()
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()

f.x = max.x
f.y = max.y
f.w = 1920
f.h = 1080
win:setFrame(f)

hs.notify.new({title="Resizing...", informativeText="1920x1080"}):send()
end)

Aerosnap

https://blog.jverkamp.com/2016/02/08/duplicating-aerosnap-on-osx-with-hammerspoon/

[Open API] Alading Bookstore Open API

Aladin Open API

키 인증 방식으로 일반 1일 호출 5000회 가능하다.

http://blog.aladin.co.kr/openapi/category/29154404?communitytype=MyPaper

TTB 가입 방법

여기 http://www.aladdin.co.kr/ttb/wjoinus.aspx 에서 TTB 가입한다. 승인 완료되면 TTB Key값이 발급된다.

TTB Key값은 http://www.aladin.co.kr/ttb/wblog_manage.aspx 이 페이지에서 조회하실 수 있습니다. 이 키값은 OPENAPI 키값으로 사용됩니다.

상품 API

여기 http://blog.aladin.co.kr/openapi/category/29154402?communitytype=MyPaper 설명되어 있다.

  • 제공 리스트 종류
  • 신간 전체 리스트
  • 주목한 만한 신간 리스트
  • 편집자 추천 리스트(카테고리로만 조회 가능 - 국내도서/음반/외서 만 지원)
  • 베스트셀러
  • 북플 베스트셀러(국내도서 만 조회 가능)

요청 URL : http://www.aladin.co.kr/ttb/api/ItemList.aspx

요청 URL샘플 :

1
http://www.aladin.co.kr/ttb/api/ItemList.aspx?ttbkey=TTBKey&QueryType=ItemNewAll&MaxResults=10&start=1&SearchTarget=Book&output=xml&Version=20131101

상품 json 형식

item array 밑에 결과 데이터가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
{
"version": "20131101",
"logo": "http://image.aladin.co.kr/img/header/2011/aladin_logo_new.gif",
"title": "알라딘 베스트셀러 리스트 - 소설/시/희곡",
"link": "http://www.aladin.co.kr/shop/common/wbest.aspx?BestType=Bestseller&BranchType=1&CID=1&Year=2013&Month=11&Week=1&partner=openAPI",
"pubDate": "Tue, 05 Nov 2013 07:48:18 GMT",
"totalResults": 200,
"startIndex": 1,
"itemsPerPage": 10,
"query": "QueryType=BESTSELLER;CategoryId=1;Year=2013;Month=11;Week=1",
"searchCategoryId": 1,
"searchCategoryName": "소설/시/희곡",
"item": [
{
"title": "제3인류 1",
"link": "http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8932916373&partner=openAPI",
"author": "베르나르 베르베르 지음, 이세욱 옮김",
"pubDate": "2013-10-21",
"description": "베르나르 베르베르 특유의 상상력으로 축조한 장대한 스케일의 과학 소설. 남극. 저명한 고생물학자 샤를 웰즈의 탐사대가 17미터에 달하는 거인의 유골들을 발굴한다. 그러나 인류사를 다시 쓰게 만들 이 중대한 발견은 발굴 현장의 사고와 함께 곧바로 파묻히고 마는데…",
"isbn": "8932916373",
"isbn13": "9788932916378",
"itemId": 32136853,
"priceSales": 12420,
"priceStandard": 13800,
"mallType": "BOOK",
"stockStatus": "",
"mileage": 1250,
"cover": "http://image.aladin.co.kr/product/3213/68/coversum/8932916373_2.jpg",
"publisher": "열린책들",
"salesPoint": 72420,
"fixedPrice": true,
"customerReviewRank": 9,
"bestRank": 1,
"subInfo": {
"ebookList": [
{
"itemId": 32241318,
"isbn": "E893291637",
"priceSales": 8100,
"link": "http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=E893291637&partner=openAPI"
}
],
"usedList": {
"aladinUsed": {
"itemCount": 0,
"minPrice": 0,
"link": "http://www.aladin.co.kr/shop/UsedShop/wuseditemall.aspx?ISBN=8932916373&TabType=2&partner=openAPI"
},
"userUsed": {
"itemCount": 9,
"minPrice": 8900,
"link": "http://www.aladin.co.kr/shop/UsedShop/wuseditemall.aspx?ISBN=8932916373&TabType=1&partner=openAPI"
}
}
}
},
{
"title": "제3인류 2",
"link": "http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8932916381&partner=openAPI",
"author": "베르나르 베르베르 지음, 이세욱 옮김",
"pubDate": "2013-10-21",
"description": "베르나르 베르베르 특유의 상상력으로 축조한 장대한 스케일의 과학 소설. 남극. 저명한 고생물학자 샤를 웰즈의 탐사대가 17미터에 달하는 거인의 유골들을 발굴한다. 그러나 인류사를 다시 쓰게 만들 이 중대한 발견은 발굴 현장의 사고와 함께 곧바로 파묻히고 마는데…",
"isbn": "8932916381",
"isbn13": "9788932916385",
"itemId": 32136901,
"priceSales": 12420,
"priceStandard": 13800,
"mallType": "BOOK",
"stockStatus": "",
"mileage": 1250,
"cover": "http://image.aladin.co.kr/product/3213/69/coversum/8932916381_2.jpg",
"publisher": "열린책들",
"salesPoint": 50880,
"fixedPrice": true,
"customerReviewRank": 10,
"bestRank": 2,
"subInfo": {
"ebookList": [
{
"itemId": 32241317,
"isbn": "E893291638",
"priceSales": 8100,
"link": "http://www.aladin.co.kr/shop/wproduct.aspx?ISBN=E893291638&partner=openAPI"
}
],
"usedList": {
"aladinUsed": {
"itemCount": 0,
"minPrice": 0,
"link": "http://www.aladin.co.kr/shop/UsedShop/wuseditemall.aspx?ISBN=8932916381&TabType=2&partner=openAPI"
},
"userUsed": {
"itemCount": 3,
"minPrice": 10500,
"link": "http://www.aladin.co.kr/shop/UsedShop/wuseditemall.aspx?ISBN=8932916381&TabType=1&partner=openAPI"
}
}
}
}
]
}