Skip to content

Commit

Permalink
Merge pull request #78 from wrjlewis/june-updates
Browse files Browse the repository at this point in the history
June updates

+ Support for Notion's new feature 'Projects', which broke how icons were displayed and subsequent results
+ if enableIcons is not selected, fixed a bug where the iconpath would be displayed inline with the results
+ Added ability to copy search result to clipboard, rather than open in the browser with CMD+Enter. wrjlewis/notion-search-alfred5-workflow#6
+ Fixed issue where braces would cause cookie parsing to fail, specifically when trying to load recently viewed pages. wrjlewis/notion-search-alfred5-workflow#5
  • Loading branch information
wrjlewis authored Jun 2, 2023
2 parents fb96833 + 014ac86 commit 1f4945a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 48 deletions.
98 changes: 72 additions & 26 deletions info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
<key>vitoclose</key>
<false/>
</dict>
<dict>
<key>destinationuid</key>
<string>2A617635-BC53-4025-A598-0A8B1E6C434B</string>
<key>modifiers</key>
<integer>1048576</integer>
<key>modifiersubtext</key>
<string>Copy to clipboard</string>
<key>vitoclose</key>
<false/>
</dict>
</array>
</dict>
<key>createdby</key>
Expand All @@ -42,6 +52,25 @@
<string>Notion Search</string>
<key>objects</key>
<array>
<dict>
<key>config</key>
<dict>
<key>browser</key>
<string></string>
<key>spaces</key>
<string></string>
<key>url</key>
<string></string>
<key>utf8</key>
<false/>
</dict>
<key>type</key>
<string>alfred.workflow.action.openurl</string>
<key>uid</key>
<string>FCE03E9D-F992-4B21-9A77-E72D5130DF80</string>
<key>version</key>
<integer>1</integer>
</dict>
<dict>
<key>config</key>
<dict>
Expand Down Expand Up @@ -91,27 +120,6 @@
<key>version</key>
<integer>3</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>browser</key>
<string></string>
<key>skipqueryencode</key>
<false/>
<key>skipvarencode</key>
<false/>
<key>spaces</key>
<string></string>
<key>url</key>
<string></string>
</dict>
<key>type</key>
<string>alfred.workflow.action.openurl</string>
<key>uid</key>
<string>FCE03E9D-F992-4B21-9A77-E72D5130DF80</string>
<key>version</key>
<integer>1</integer>
</dict>
<dict>
<key>config</key>
<dict>
Expand Down Expand Up @@ -209,9 +217,42 @@ fi</string>
<key>version</key>
<integer>2</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>autopaste</key>
<false/>
<key>clipboardtext</key>
<string>{query}</string>
<key>ignoredynamicplaceholders</key>
<false/>
<key>transient</key>
<false/>
</dict>
<key>type</key>
<string>alfred.workflow.output.clipboard</string>
<key>uid</key>
<string>2A617635-BC53-4025-A598-0A8B1E6C434B</string>
<key>version</key>
<integer>3</integer>
</dict>
</array>
<key>readme</key>
<string>notion-search-alfred-workflow
<string>****** PLEASE NOTE ******
Alfred 5 download now available here:
https://github.com/wrjlewis/notion-search-alfred5-workflow/releases/latest/download/Notion.Search.Alfred.5.alfredworkflow
Usual automatic updates will follow once you've updated to the Alfred 5 version of this workflow.
If you are on alfred 4, you do not need to do anything and updates will continue as usual.
****** PLEASE NOTE ******
notion-search-alfred-workflow
An Alfred workflow to search Notion.so with instant results
Simply type your keyword into Alfred (default: ns) to see instant search results from Notion that mimic the Quick Find function in the Notion webapp. Selecting a search result takes you to that page in Notion in your default web browser.
Expand All @@ -225,6 +266,13 @@ https://www.alfredforum.com/topic/14451-notionso-instant-search-workflow/
Thanks!</string>
<key>uidata</key>
<dict>
<key>2A617635-BC53-4025-A598-0A8B1E6C434B</key>
<dict>
<key>xpos</key>
<integer>260</integer>
<key>ypos</key>
<integer>330</integer>
</dict>
<key>7DD3BDE5-A157-42E5-9376-F681FB50A4EE</key>
<dict>
<key>xpos</key>
Expand All @@ -251,8 +299,6 @@ Thanks!</string>
<real>50</real>
</dict>
</dict>
<key>userconfigurationconfig</key>
<array/>
<key>variables</key>
<dict>
<key>cookie</key>
Expand All @@ -276,8 +322,8 @@ Thanks!</string>
<string>notionSpaceId</string>
</array>
<key>version</key>
<string>0.5.1-alfred4</string>
<string>0.5.2-alfred4</string>
<key>webaddress</key>
<string>https://github.com/wrjlewis/notion-search-alfred-workflow/</string>
</dict>
</plist>
</plist>
55 changes: 33 additions & 22 deletions notion.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import unicodedata
import time
import urllib.parse, urllib.error
import re
from urllib.request import Request, urlopen
from http.cookies import SimpleCookie

Expand All @@ -24,14 +25,12 @@
notionSpaceId = os.environ['notionSpaceId']
cookie = os.environ['cookie']

# convert cookie string to dict for later use
bakedCookie = SimpleCookie()
bakedCookie.load(cookie)
# even though SimpleCookie is dictionary-like, it internally uses a Morsel object
# Manually construct a dictionary instead.
bakedCookies = {}
for key, morsel in bakedCookie.items():
bakedCookies[key] = morsel.value
# try to get notion_user_id from cookie
notion_user_id = None
try:
notion_user_id = re.search('notion_user_id=(.[^;]+);', cookie).group(1)
except:
pass

# get useDesktopClient env variable and convert to boolean for use later, default to false
useDesktopClient = os.environ['useDesktopClient']
Expand Down Expand Up @@ -144,9 +143,17 @@ def downloadandgetfilepath(searchresultobjectid, imageurl):
+ searchresultobjectid \
+ "&width=120&cache=v2"

# construct filepath consisting of workspace id + filename
filepath = downloadurl[downloadurl.rfind('%2F') + 3:]
filepath = filepath[:filepath.rfind('?')]
# construct filepath consisting of workspace id + filename
# Notion uses many different image url types, some encoded some not
# hence the catasprophe here extracting a filename
# should probably try to normalise all urls and extract filename with one method
if downloadurl.rfind('%2F') < 0:
extractfromdownloadurl = urllib.parse.quote(downloadurl.encode('utf8'), safe='')
else:
extractfromdownloadurl = downloadurl
filepath = extractfromdownloadurl[extractfromdownloadurl.rfind('%2F') + 3:]
if '?' in filepath:
filepath = filepath[:filepath.rfind('?')]
if '%3F' in filepath:
filepath = filepath[:filepath.rfind('%3F')]
filepath = "icons/" + searchresultobjectid + "_" + filepath
Expand Down Expand Up @@ -186,7 +193,7 @@ def downloadandgetfilepath(searchresultobjectid, imageurl):
def convertsvgtopng(filepath):
if (cairosvgInstalled):
pngfilepath = filepath[:-3] + "png"
svg2png(url=filepath, write_to=pngfilepath)
svg2png(url=filepath, write_to=pngfilepath, output_width=200, output_height=200)
return pngfilepath
else:
return None
Expand Down Expand Up @@ -218,8 +225,9 @@ def geticonpath(searchresultobjectid, notionicon):
# is icon a web url or svg icon? If so, download it to icons/
if (notionicon[0:7] == "/icons/"):
notionicon = "https://www.notion.so/image/https%3A%2F%2Fwww.notion.so%2Ficons%2F" + notionicon[7:] + "?"
if "http" in notionicon:
iconpath = downloadandgetfilepath(searchresultobjectid, notionicon)
if (notionicon[0:8] == "/images/"):
notionicon = "https://www.notion.so" + notionicon
iconpath = downloadandgetfilepath(searchresultobjectid, notionicon)

return iconpath

Expand Down Expand Up @@ -262,12 +270,12 @@ def createSubtitleChain(recordMap, id):
# Else show notion search results for the query given
if not (alfredQuery and alfredQuery.strip()):
try:
if ("notion_user_id" in bakedCookies and showRecentlyViewedPages):
if (notion_user_id is not None and showRecentlyViewedPages):
headers = {"Content-type": "application/json",
"Cookie": cookie}
conn = http.client.HTTPSConnection("www.notion.so")
conn.request("POST", "/api/v3/getRecentPageVisits",
buildnotionrecentpagevisitsquery(bakedCookies.get("notion_user_id")), headers)
buildnotionrecentpagevisitsquery(notion_user_id), headers)
response = conn.getresponse()
data = response.read()
conn.close()
Expand Down Expand Up @@ -325,16 +333,19 @@ def createSubtitleChain(recordMap, id):
searchResultObject.title = x.get('highlight').get('text')
searchResultObject.subtitle = createSubtitleChain(searchResults.recordMap, searchResultObject.id)
if "format" in searchResults.recordMap.get('block').get(searchResultObject.id).get('value'):
if "page_icon" in searchResults.recordMap.get('block').get(searchResultObject.id).get('value').get('format'):
if enableIcons:
if enableIcons:
if "page_icon" in searchResults.recordMap.get('block').get(searchResultObject.id).get('value').get('format'):
searchResultObject.icon = geticonpath(searchResultObject.id,
searchResults.recordMap.get('block').get(searchResultObject.id)
.get('value').get('format').get('page_icon'))
else:
searchResultObject.icon = None
searchResultObject.title = searchResults.recordMap.get('block').get(searchResultObject.id).get(
'value').get('format').get('page_icon') + " " + searchResultObject.title

if searchResults.recordMap.get('block').get(searchResultObject.id).get('value').get('type') == "collection_view":
collectionPointerId = searchResults.recordMap.get('block').get(searchResultObject.id).get('value').get('format').get('collection_pointer').get('id')
searchResultObject.icon = geticonpath(searchResultObject.id, searchResults.recordMap.get('collection').get(collectionPointerId).get('value').get('icon'))
else:
searchResultObject.icon = None
searchResultObject.title = searchResultObject.title

searchResultObject.link = getnotionurl() + searchResultObject.id.replace("-", "")
searchResultList.append(searchResultObject)
except Exception as e:
Expand Down

0 comments on commit 1f4945a

Please sign in to comment.