Skip to content

Commit 15d45e3

Browse files
committed
Initial commit
0 parents  commit 15d45e3

26 files changed

+6009
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
.DS_Store
36.8 KB
Loading
36.8 KB
Loading
36.8 KB
Loading

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
all:
2+
mkdir build
3+
zip -qR build/alfred-confluence.alfredworkflow "*"
4+

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Alfred Confluence Workflow
2+
3+
4+
5+
6+
## Getting Started
7+
8+
1. Download Alfred Confluence from the Github releases page.
9+
2. Install Alfred Confluence in Alfred.
10+
3. Configure Alfred Confluence with the following commands
11+
3. cqs_baseurl - set the Confluence Base Url
12+
3. cqs_username - set your Confluence usename
13+
3. cqs_password - set your Confluence password (it will be stored securely in the MacOS keychain)
14+
4. Then use the following command to search your Confluence system: {{c my search tem}}
15+
16+
17+
18+
# Advanced Configuration
19+
20+
If you work with multiple Confluence systems, you have to create the file {{~/.alfred-confluence.json}} that looks like the following:
21+
22+
''''
23+
[
24+
{
25+
"key": "wkc",
26+
"name": "www.k15t.com",
27+
"baseUrl" : "https://www.k15t.com",
28+
"username" : "stefan",
29+
"password" : "your-unencrypted-password"
30+
},
31+
{
32+
"key": "cl",
33+
"name": "Cloud",
34+
"baseUrl" : "https://k15t.jira.com/wiki",
35+
"username" : "stefan",
36+
"password" : "your-unencrypted-password"
37+
}
38+
]
39+
''''
40+
41+
Please be aware that this will store you password in clear text on your file system.
42+
43+
44+
# Release History
45+
46+
## 1.0.0
47+
48+
Initial release.

alfred-confluence.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import argparse
2+
import json
3+
import sys
4+
from HTMLParser import HTMLParser
5+
from lib.workflow import Workflow, web, PasswordNotFound
6+
from os.path import expanduser
7+
from urlparse import urlparse
8+
9+
log = None
10+
11+
PROP_BASEURL = 'confluence_baseUrl'
12+
PROP_USERNAME = 'confluence_username'
13+
PROP_PASSWORD = 'confluence_password'
14+
15+
16+
def getConfluenceBaseUrl():
17+
if wf.settings.get(PROP_BASEURL):
18+
return wf.settings[PROP_BASEURL]
19+
else:
20+
wf.add_item(title='No Confluence Base URL set. Please run confluence_baseurl', valid=False)
21+
wf.send_feedback()
22+
return 0
23+
24+
25+
def getConfluenceUsername():
26+
if wf.settings.get(PROP_USERNAME):
27+
return wf.settings[PROP_USERNAME]
28+
else:
29+
wf.add_item(title='No Confluence Username set. Please run confluence_username', valid=False)
30+
wf.send_feedback()
31+
return 0
32+
33+
34+
def getConfluencePassword():
35+
try:
36+
return wf.get_password(PROP_PASSWORD)
37+
except PasswordNotFound:
38+
wf.add_item(title='No Confluence Password set. Please run confluence_password', valid=False)
39+
wf.send_feedback()
40+
return 0
41+
42+
43+
def main(wf):
44+
parser = argparse.ArgumentParser()
45+
parser.add_argument('--baseUrl', dest='baseUrl', nargs='?', default=None)
46+
parser.add_argument('--username', dest='username', nargs='?', default=None)
47+
parser.add_argument('--password', dest='password', nargs='?', default=None)
48+
parser.add_argument('query', nargs='?', default=None)
49+
args = parser.parse_args(wf.args)
50+
51+
52+
if args.baseUrl:
53+
wf.settings[PROP_BASEURL] = args.baseUrl
54+
return 0
55+
56+
if args.username:
57+
wf.settings[PROP_USERNAME] = args.username
58+
return 0
59+
60+
if args.password:
61+
wf.save_password(PROP_PASSWORD, args.password)
62+
return 0
63+
64+
try:
65+
# lookup config for system
66+
args = wf.args[0].split()
67+
config = findConfig(args)
68+
69+
if config.get('isFallback') is None:
70+
query = ' '.join(args[1:])
71+
else:
72+
query = ' '.join(args)
73+
74+
except:
75+
query = wf.args[0]
76+
config = dict(
77+
baseUrl=getConfluenceBaseUrl(),
78+
name='',
79+
username=getConfluenceUsername(),
80+
password=getConfluencePassword()
81+
)
82+
83+
# query Confluence
84+
url = config['baseUrl'] + '/rest/quicknav/1/search?os_authType=basic&query=%s' % query
85+
86+
log.debug('Quick Search URL: ' + url)
87+
88+
r = web.get(url, params=dict(query=query), auth=(config['username'], config['password']))
89+
90+
# throw an error if request failed
91+
# Workflow will catch this and show it to the user
92+
r.raise_for_status()
93+
94+
# Parse the JSON returned by pinboard and extract the posts
95+
result = r.json()
96+
contentGroups = result['contentNameMatches']
97+
98+
# Loop through the returned posts and add an item for each to
99+
# the list of results for Alfred
100+
for contentGroup in contentGroups:
101+
for content in contentGroup:
102+
# filter results to only contain pages and blog posts (and search site link)
103+
if content['className'] in ['content-type-page', 'content-type-blogpost', 'search-for']:
104+
if (content.get('spaceName')):
105+
subtitle = content['spaceName']
106+
else:
107+
subtitle = 'Use full Confluence Search'
108+
109+
110+
wf.add_item(title=htmlParser.unescape(content['name']),
111+
subtitle=config['name'] + subtitle,
112+
arg=getBaseUrlWithoutPath(config['baseUrl']) + content['href'],
113+
valid=True,
114+
icon='assets/' + content['className'] + '.png')
115+
116+
# Send the results to Alfred as XML
117+
wf.send_feedback()
118+
119+
120+
def findConfig(args):
121+
homeDir = expanduser('~')
122+
with open(homeDir + '/.alfred-confluence.json') as configFile:
123+
configs = json.load(configFile)
124+
125+
126+
if len(args) > 1:
127+
for config in configs:
128+
if args[0].lower() == config['key'].lower():
129+
return config
130+
131+
# Fallback to first entry
132+
configs[0]['isFallback'] = True
133+
return configs[0]
134+
135+
136+
def getBaseUrlWithoutPath(baseUrl):
137+
parsedBaseUrl = urlparse(baseUrl)
138+
baseUrlWithoutPath = parsedBaseUrl.scheme + '://' + parsedBaseUrl.hostname
139+
return baseUrlWithoutPath
140+
141+
142+
if __name__ == u'__main__':
143+
wf = Workflow()
144+
htmlParser = HTMLParser()
145+
log = wf.logger
146+
sys.exit(wf.run(main))

assets/banner.png

337 KB
Loading

assets/content-type-blogpost.png

10.8 KB
Loading

assets/content-type-page.png

7.87 KB
Loading

0 commit comments

Comments
 (0)