Skip to content

Commit db9dae9

Browse files
author
ryanss
committed
Add basic search
Plugin will now display search results from Algolia search API when optional argument passed to `:HackerNews` command is not an alternative page name (ask, show, etc) or item id. Currently only sorted by popularity with no ability to sort other ways. Close #26
1 parent b4f251b commit db9dae9

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Basic Usage
1919
* Open the Hacker News front page in Vim by executing the `:HackerNews` command
2020
* The HackerNews command takes an optional parameter to view items other
2121
than the top stories on the front page: `ask`, `show`, `shownew`, `jobs`,
22-
`best`, `active`, `newest`, `noobstories`, or `item id`
22+
`best`, `active`, `newest`, `noobstories`, `<item id>`, or `<search query>`
2323
* Press lowercase `o` to open links in Vim
2424
* Press uppercase `O` to open links in default web browser
2525
* Numbered lines with story titles on the front page link to the story url

ftplugin/hackernews.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,33 @@
1010
# Version: 0.3-dev
1111

1212

13-
from __future__ import print_function
13+
from __future__ import print_function, division
1414
import binascii
1515
import json
1616
import re
17+
import sys
1718
import textwrap
1819
import vim
1920
import webbrowser
20-
import sys
21+
from datetime import datetime
2122
if sys.version_info >= (3, 0):
2223
from html.parser import HTMLParser
24+
from urllib.parse import quote_plus, urlparse
2325
from urllib.request import urlopen
2426
from urllib.error import HTTPError
2527
unicode = bytes
2628
unichr = chr
2729
else:
2830
from HTMLParser import HTMLParser
31+
from urllib import quote_plus
2932
from urllib2 import urlopen, HTTPError
33+
from urlparse import urlparse
3034

3135

3236
API_URL = "http://node-hnapi.herokuapp.com"
3337
MARKDOWN_URL = "http://fuckyeahmarkdown.com/go/?read=1&u="
38+
SEARCH = ("https://hn.algolia.com/api/v1/search" +
39+
"?tags=story&hitsPerPage=60&query=")
3440

3541
html = HTMLParser()
3642

@@ -66,6 +72,35 @@ def hex(s):
6672
return binascii.hexlify(s)
6773

6874

75+
def time_ago(timestamp):
76+
d = datetime.now() - datetime.fromtimestamp(timestamp)
77+
years = d.days // 365
78+
if years > 1:
79+
return "%d years ago" % (years)
80+
elif years == 1:
81+
return "%d year ago" % (years)
82+
months = d.days // 30
83+
if months > 1:
84+
return "%d months ago" % (months)
85+
elif months == 1:
86+
return "%d month ago" % (months)
87+
if d.days > 1:
88+
return "%d days ago" % (d.days)
89+
elif d.days == 1:
90+
return "%d day ago" % (d.days)
91+
hours = d.seconds // 60 // 60
92+
if hours > 1:
93+
return "%d hours ago" % (hours)
94+
elif hours == 1:
95+
return "%d hour ago" % (hours)
96+
minutes = d.seconds // 60
97+
if minutes > 1:
98+
return "%d minutes ago" % (minutes)
99+
elif minutes == 1:
100+
return "%d minute ago" % (minutes)
101+
return "%d seconds ago" % (d.seconds)
102+
103+
69104
def main():
70105
vim.command("edit .hackernews")
71106
vim.command("setlocal noswapfile")
@@ -91,12 +126,15 @@ def main():
91126
elif arg[:4] == 'http':
92127
link(url=arg)
93128
return
94-
else:
129+
elif not arg:
95130
news1 = json.loads(urlopen(API_URL+"/news", timeout=5)
96131
.read().decode('utf-8'))
97132
news2 = json.loads(urlopen(API_URL+"/news2", timeout=5)
98133
.read().decode('utf-8'))
99134
items = news1 + news2
135+
else:
136+
items = json.loads(urlopen(SEARCH+quote_plus(arg), timeout=5)
137+
.read().decode('utf-8'))['hits']
100138
except HTTPError:
101139
print("HackerNews.vim Error: %s" % str(sys.exc_info()[1].reason))
102140
return
@@ -105,6 +143,18 @@ def main():
105143
return
106144

107145
for i, item in enumerate(items):
146+
# Test if item is a result from search API
147+
if 'objectID' in item:
148+
# Convert search API results into dict similar to regular API
149+
# results so we can use same code to output results
150+
item['id'] = int(item['objectID'])
151+
item['user'] = item['author']
152+
item['type'] = "link"
153+
item['time_ago'] = time_ago(item['created_at_i'])
154+
item['comments_count'] = int(item['num_comments'])
155+
if item.get('url', False):
156+
item['domain'] = urlparse(item['url']).netloc
157+
108158
if 'title' not in item:
109159
continue
110160
if 'domain' in item:

plugin/hackernews.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ endif
2828
function! HackerNews(...)
2929
if a:0 > 0
3030
let g:hackernews_arg = a:1
31+
else
32+
let g:hackernews_arg = ""
3133
endif
3234
execute "edit .hackernews"
3335
normal! gg

0 commit comments

Comments
 (0)