Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Nested Comments. Refactoring.

  • Loading branch information...
commit e6cc99d8b9ecac6afdd952bcfe513146b1fc0e8f 1 parent de318c5
@glebpopoff authored
View
228 APIUtils.py
@@ -11,7 +11,6 @@
import urllib
import AppConfig
from google.appengine.api import urlfetch
-import DataCache
from BeautifulSoup import BeautifulSoup
from django.utils import simplejson
from structured import list2xml
@@ -22,243 +21,40 @@ def removeHtmlTags(data):
def removeNonAscii(s): return "" . join(filter(lambda x: ord(x)<128, s))
-#get cached content
-def getCache(pageId,format):
- logging.debug('getCache: %s' % pageId)
- dbData = DataCache.getData(pageId,format)
- if (dbData):
- if (DataCache.hasExpired(dbData)):
- #data has expired, remove it
- dbData[0].delete()
- return None
- else:
- logging.debug('getCache: got cached data for id %s' % id)
- return dbData[0].rec_xml
-
-#parse HN's submissions by user
-def getHackerNewsSubmittedContent(user, format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- apiURL = "%s/submitted?id=%s" % (AppConfig.hackerNewsURL, user)
- apiURLBackup = "%s/submitted?id=%s" % (AppConfig.hackerNewsURLBackup, user)
- id = '/submitted/%s' % (user)
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
+#call urlfetch to get remote data
+def fetchRemoteData(urlStr, deadline):
+ result = urlfetch.fetch(url=urlStr, deadline=deadline)
+ if result.status_code == 200:
+ return result
else:
- hnData = parsePageContent(apiURL,apiURLBackup, '/submitted', None,format)
- if (hnData):
- logging.debug('getHackerNewsSubmittedContent: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getHackerNewsSubmittedContent: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's comments by story id
-def getHackerNewsComments(articleId, format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- apiURL = "%s/item?id=%s" % (AppConfig.hackerNewsURL, articleId)
- apiURLBackup = "%s/item?id=%s" % (AppConfig.hackerNewsURLBackup, articleId)
- id = '/comments/%s' % (articleId)
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parseCommentsContent(apiURL, apiURLBackup, '/comments', None,format)
- if (hnData):
- logging.debug('getHackerNewsComments: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getHackerNewsComments: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's comments by story id
-def getHackerNewsNestedComments(articleId, format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- apiURL = "%s/item?id=%s" % (AppConfig.hackerNewsURL, articleId)
- apiURLBackup = "%s/item?id=%s" % (AppConfig.hackerNewsURLBackup, articleId)
- id = '/nestedcomments/%s' % (articleId)
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parseNestedCommentsContent(apiURL, apiURLBackup, '/nestedcomments', None,format)
- if (hnData):
- logging.debug('getHackerNewsComments: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getHackerNewsComments: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's ask content
-def getHackerNewsAskContent(page='', format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- if (page):
- return parsePageContent(AppConfig.hackerNewsAskURL, AppConfig.hackerNewsAskURLBackup, '/ask', page,format)
- else:
- id = '/ask/'
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsAskURL, AppConfig.hackerNewsAskURLBackup, '/ask', page,format)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's best content
-def getHackerNewsBestContent(page='', format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- if (page):
- return parsePageContent(AppConfig.hackerNewsBestURL, AppConfig.hackerNewsBestURLBackup, '/best', page,format)
- else:
- id = '/best/'
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsBestURL, AppConfig.hackerNewsBestURLBackup, '/best', page,format)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's newest content
-def getHackerNewsNewestContent(page='', format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- if (page):
- return parsePageContent(AppConfig.hackerNewsNewestURL, AppConfig.hackerNewsNewestURLBackup,'/newest', page,format)
- else:
- id = '/newest/'
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsNewestURL, AppConfig.hackerNewsNewestURLBackup,'/newest', page,format)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
-
-
-#get homepage second page stories
-def getHackerNewsSecondPageContent(page='', format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- if (page):
- return parsePageContent(AppConfig.hackerNewsPage2URL, AppConfig.hackerNewsPage2URLBackup,'/news2', page,format)
- else:
- id = '/news2'
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsPage2URL, AppConfig.hackerNewsPage2URLBackup, '/news2', page,format)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
-
-#get latest homepage stories
-def getHackerNewsLatestContent(page='', format='json', url='', referer='', remote_addr='', limit=1):
- #only cache homepage data
- limit = int(limit)
- if (page):
- return parsePageContent(AppConfig.hackerNewsURL, AppConfig.hackerNewsURLBackup, '/latest', page,format,limit)
- else:
- id = '/latest/%s' % limit
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsURL,AppConfig.hackerNewsURLBackup, '/latest', page,format,limit)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
-
-#parse HN's homepage
-def getHackerNewsPageContent(page='', format='json', url='', referer='', remote_addr=''):
- #only cache homepage data
- if (page):
- return parsePageContent(AppConfig.hackerNewsURL, AppConfig.hackerNewsURLBackup, '/news', page,format)
- else:
- id = '/news/'
- cachedData = getCache(id,format)
- if (cachedData):
- return cachedData
- else:
- hnData = parsePageContent(AppConfig.hackerNewsURL, AppConfig.hackerNewsURLBackup, '/news', page,format)
- if (hnData):
- logging.debug('getCache: storing cached value for id %s' % id)
- DataCache.putData(id, format,removeNonAscii(hnData), url, referer, remote_addr)
- return hnData
- else:
- logging.warning('getCache: unable to retrieve data for id %s' % id)
- return ''
+ logging.error('fetchRemoteData: unable to get remote data: %s' % urlStr)
+ raise Exception("fetchRemoteData: failed")
#call remote server to get data. If failed (timeout), try again and again and again and again (4 attempts because urlfetch on the GAE f-ing sucks)
def getRemoteData(urlStr, backupUrl):
#attempt #1
try:
logging.debug('getRemoteData: Attempt #1: %s' % urlStr)
- result = urlfetch.fetch(url=urlStr, deadline=30)
- if result.status_code == 200:
- return result
- else:
- logging.error('getRemoteData: unable to get remote data...Attempt #1: %s' % urlStr)
- raise Exception("getRemoteData: Attempt #1 failed")
+ return fetchRemoteData(urlStr, 30)
except:
#attempt #2
try:
logging.debug('getRemoteData: First attempt failed... Attempt #2(Backup URL): %s' % backupUrl)
- result = urlfetch.fetch(url=backupUrl, deadline=30)
- if result.status_code == 200:
- return result
- else:
- logging.error('getRemoteData: unable to get remote data...Attempt #2')
- raise Exception("getRemoteData: Attempt #2 failed")
+ return fetchRemoteData(backupUrl, 30)
except:
#attempt #3
try:
logging.debug('getRemoteData: First attempt failed... Attempt #3: %s' % urlStr)
- result = urlfetch.fetch(url=urlStr, deadline=30)
- if result.status_code == 200:
- return result
- else:
- logging.error('getRemoteData: unable to get remote data...Attempt #3')
- raise Exception("getRemoteData: Attempt #3 failed")
+ return fetchRemoteData(urlStr, 30)
except:
#attempt #4
try:
logging.debug('getRemoteData: First attempt failed... Attempt #4 (Backup URL): %s' % backupUrl)
- result = urlfetch.fetch(url=backupUrl, deadline=30)
- if result.status_code == 200:
- return result
- else:
- logging.error('getRemoteData: unable to get remote data...Attempt #4')
- return None
+ return fetchRemoteData(backupUrl, 30)
except:
logging.error('getRemoteData: unable to get remote data...Attempt #4. Stack')
return None
- return jsonData
+ return None
#parse content using Beautiful Soup
def parsePageContent(hnAPIUrl,hnBackupAPIUrl, apiURL, page='',format='json',limit=0):
View
7 GetHNAskHandler.py
@@ -16,7 +16,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from BeautifulSoup import BeautifulSoup
@@ -31,11 +31,10 @@ def get(self,format='json',page=''):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsAskContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsAskContent(page,format,self.request.url, referer, self.request.remote_addr)
if (not returnData or returnData == None or returnData == '' or returnData == 'None'):
#call the service again this time without the pageID
- returnData = APIUtils.getHackerNewsAskContent('',format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsAskContent('',format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/ask', self.request.remote_addr, referer)
View
7 GetHNBestHandler.py
@@ -16,7 +16,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from BeautifulSoup import BeautifulSoup
@@ -31,11 +31,10 @@ def get(self,format='json',page=''):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsBestContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsBestContent(page,format,self.request.url, referer, self.request.remote_addr)
if (not returnData or returnData == None or returnData == '' or returnData == 'None'):
#call the service again this time without the pageID
- returnData = APIUtils.getHackerNewsBestContent('',format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsBestContent('',format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/best', self.request.remote_addr, referer)
View
7 GetHNCommentsHandler.py
@@ -18,7 +18,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from BeautifulSoup import BeautifulSoup
@@ -33,9 +33,8 @@ def get(self,format,id):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsComments(id,format,self.request.url, referer, self.request.remote_addr)
-
+ returnData = APIContent.getHackerNewsComments(id,format,self.request.url, referer, self.request.remote_addr)
+
#track this request
GAHelper.trackGARequests('/comments/%s' % (id), self.request.remote_addr, referer)
View
5 GetHNLatestHandler.py
@@ -18,7 +18,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
class HackerNewsLatestPageHandler(webapp.RequestHandler):
@@ -32,8 +32,7 @@ def get(self,format='json',limit=1):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsLatestContent('',format,self.request.url, referer, self.request.remote_addr, limit)
+ returnData = APIContent.getHackerNewsLatestContent('',format,self.request.url, referer, self.request.remote_addr, limit)
#track this request
GAHelper.trackGARequests('/latest', self.request.remote_addr, referer)
View
5 GetHNNestedCommentsHandler.py
@@ -17,7 +17,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from BeautifulSoup import BeautifulSoup
@@ -32,8 +32,7 @@ def get(self,format,id):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsNestedComments(id,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsNestedComments(id,format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/nestedcomments/%s' % (id), self.request.remote_addr, referer)
View
7 GetHNNewestHandler.py
@@ -16,7 +16,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from BeautifulSoup import BeautifulSoup
@@ -31,11 +31,10 @@ def get(self,format='json',page=''):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsNewestContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsNewestContent(page,format,self.request.url, referer, self.request.remote_addr)
if (not returnData or returnData == None or returnData == '' or returnData == 'None'):
#call the service again this time without the pageID
- returnData = APIUtils.getHackerNewsNewestContent('',format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsNewestContent('',format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/newest', self.request.remote_addr, referer)
View
7 GetHNPageContentHandler.py
@@ -18,7 +18,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
class HackerNewsPageHandler(webapp.RequestHandler):
@@ -32,11 +32,10 @@ def get(self,format='json',page=''):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsPageContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsPageContent(page,format,self.request.url, referer, self.request.remote_addr)
if (not returnData or returnData == None or returnData == '' or returnData == 'None'):
#call the service again this time without the pageID
- returnData = APIUtils.getHackerNewsPageContent('',format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsPageContent('',format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/news', self.request.remote_addr, referer)
View
4 GetHNRSSHandler.py
@@ -17,7 +17,7 @@
import Formatter
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
class HackerNewsRSSHandler(webapp.RequestHandler):
#controller main entry
@@ -26,7 +26,7 @@ def get(self,format='json'):
self.response.headers['Content-Type'] = Formatter.contentType(format)
returnData = MutableString()
- returnData = APIUtils.getHackerNewsRSS(format)
+ returnData = APIContent.getHackerNewsRSS(format)
referer = ''
if ('HTTP_REFERER' in os.environ):
View
7 GetHNSecondPageHandler.py
@@ -18,7 +18,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
from google.appengine.api import urlfetch
@@ -33,11 +33,10 @@ def get(self,format='json',page=''):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsSecondPageContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsSecondPageContent(page,format,self.request.url, referer, self.request.remote_addr)
if (not returnData or returnData == None or returnData == '' or returnData == 'None'):
#call the service again
- returnData = APIUtils.getHackerNewsSecondPageContent(page,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsSecondPageContent(page,format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/news2', self.request.remote_addr, referer)
View
5 GetHNSubmittedHandler.py
@@ -18,7 +18,7 @@
import AppConfig
import GAHelper
from xml.sax.saxutils import escape
-import APIUtils
+import APIContent
import GAHelper
class HackerNewsSubmittedHandler(webapp.RequestHandler):
@@ -31,8 +31,7 @@ def get(self,format,user):
if ('HTTP_REFERER' in os.environ):
referer = os.environ['HTTP_REFERER']
- returnData = MutableString()
- returnData = APIUtils.getHackerNewsSubmittedContent(user,format,self.request.url, referer, self.request.remote_addr)
+ returnData = APIContent.getHackerNewsSubmittedContent(user,format,self.request.url, referer, self.request.remote_addr)
#track this request
GAHelper.trackGARequests('/submitted/%s' % (user), self.request.remote_addr, referer)
View
2  app.yaml
@@ -1,5 +1,5 @@
application: hndroidapi
-version: 1
+version: 2
runtime: python
api_version: 1
View
2  main.py
@@ -21,7 +21,7 @@
class MainHandler(webapp.RequestHandler):
def get(self):
- template_values = {'last_updated': '10/22/11'}
+ template_values = {'last_updated': '10/23/11'}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'index.html')
self.response.out.write(template.render(path, template_values))
View
103 templates/index.html
@@ -35,7 +35,7 @@
function getLatestAdvanced()
{
- window.location = apiURL + '/latest/format/' + format('latest-format') + '/limit/' + elm('latest-limit')
+ window.location = apiURL + '/latest/format/' + format('latest-format') + '/limit/' + elm('latest-limit');
}
function getBestSimple()
@@ -50,32 +50,37 @@
function getNewsAdvanced()
{
- window.location = apiURL + '/news/format/' + format('newsadvanced-format') + '/page/' + elm('newsadvanced-pageid')
+ window.location = apiURL + '/news/format/' + format('newsadvanced-format') + '/page/' + elm('newsadvanced-pageid');
}
function getNewestAdvanced()
{
- window.location = apiURL + '/newest/format/' + format('newestadvanced-format') + '/page/' + elm('newestadvanced-pageid')
+ window.location = apiURL + '/newest/format/' + format('newestadvanced-format') + '/page/' + elm('newestadvanced-pageid');
}
function getAskAdvanced()
{
- window.location = apiURL + '/ask/format/' + format('ask-format') + '/page/' + elm('ask-pageid')
+ window.location = apiURL + '/ask/format/' + format('ask-format') + '/page/' + elm('ask-pageid');
}
function getBestAdvanced()
{
- window.location = apiURL + '/best/format/' + format('best-format') + '/page/' + elm('best-pageid')
+ window.location = apiURL + '/best/format/' + format('best-format') + '/page/' + elm('best-pageid');
}
function getByUser()
{
- window.location = apiURL + '/submitted/format/' + format('user-format') + '/user/' + elm('user-pageid')
+ window.location = apiURL + '/submitted/format/' + format('user-format') + '/user/' + elm('user-pageid');
}
function getComments()
{
- window.location = apiURL + '/comments/format/' + format('comments-format') + '/id/' + elm('comments-pageid')
+ window.location = apiURL + '/comments/format/' + format('comments-format') + '/id/' + elm('comments-pageid');
+ }
+
+ function getNestedComments()
+ {
+ window.location = apiURL + '/nestedcomments/format/' + format('nestedcomments-format') + '/id/' + elm('nestedcomments-pageid');
}
function elm(id) { return (document.getElementById(id)) ? document.getElementById(id).value : '' }
@@ -101,7 +106,9 @@
<div id="app-header">
<h3>Last updated: {{last_updated}}</h3>
<p>
- Update (10/22/11): <i>Thanks to my friend Eric I now have a dedicated server to handle API traffic. The API has been down for a few hours on Friday, October 21st because of GAE urlfetch (DownloadError: ApplicationError: 2) errors. Apparently, GAE started to deny requests to HN so the data had to be retrieved from another server. The API still runs on GAE but the data is being fetched from another server and then provided to GAE instances for processing. </i>
+ <small>Update (10/23/11): The API now supports nested comments as a new API call (/nestedcomments) (thanks to Suan Aik Yeo). The old comments API (/comments) has been deprecated.</small>
+ <br/>
+ <small>Update (10/22/11): Thanks to my friend Eric I now have a dedicated server to handle API traffic. The API has been down for a few hours on Friday, October 21st because of GAE urlfetch (DownloadError: ApplicationError: 2) errors. Apparently, GAE started to deny requests to HN so the data had to be retrieved from another server. The API still runs on GAE but the data is being fetched from another server and then provided to GAE instances for processing. </small>
</p>
<span>The API is currently in beta and was developed for the <a href="https://market.android.com/details?id=com.glebpopov.hackernews" target="_new">Hacker News Droid</a> app. The API is built in Python and hosted on AppEngine. I used the <a href="http://www.crummy.com/software/BeautifulSoup/">Beautiful Soup</a> library for HTML parsing/scraping and an external dedicated box (generously provided by <script>var user='kigath'; document.writeln('<a href="mailto:' + user + 'i' + '@' + 'g' + 'mai' + 'l.com">' + 'Eric Kigathi</a>')</script>) to retrieve content from HN so it can be processed by GAE instances and served up.
<br/>
@@ -118,12 +125,13 @@
<ul>
<li><a href='#homepage'>Homepage</a></li>
<li><a href='#homepage2'>Homepage Page 2</a></li>
+ <li><a href='#comments'>Comments</a>&nbsp;<small>(deprecated)</small></li>
+ <li><a href='#nestedcomments'>Nested Comments</a></li>
<li><a href='#latest'>Latest</a></li>
<li><a href='#newest'>Newest</a></li>
<li><a href='#best'>Best</a></li>
<li><a href='#ask'>Ask</a></li>
<li><a href='#user'>Submitted</a></li>
- <li><a href='#user'>Comments</a></li>
</ul>
</p>
<hr >
@@ -182,6 +190,56 @@
</fieldset>
<hr >
+<a name="comments"></a>
+<h2>Comments by Story ID (Deprecated as of 10/23/11)</h2>
+<fieldset>
+ <b>Returns story comments by id </b>&nbsp;<small>(returns XML or JSON)</small><br /><br />
+ <table>
+ <tr>
+ <td>URL:</td>
+ <td>http://hndroidapi.appspot.com/comments/format/<em>&lt;format&gt;</em>/id/<em>&lt;id&gt;</em></td>
+ </tr>
+ <tr>
+ <td>Story Id:</td>
+ <td><input type="text" id="comments-pageid" name="comments-pageid" />&nbsp;<small>(e.g. 3423232)</small></td>
+ </tr>
+ <tr>
+ <td>Format:</td>
+ <td><input type="radio" name="comments-format" value="json" checked='checked'/>JSON&nbsp;<input type="radio" name="comments-format" value="xml"/>XML</td>
+ </tr>
+ <tr>
+ <td colspan='2'><input type="button" value=" Test " onclick="getComments()" /></td>
+ </tr>
+ </table>
+ <br />
+</fieldset>
+
+<hr >
+<a name="nestedcomments"></a>
+<h2>Nested Comments by Story ID</h2>
+<fieldset>
+ <b>Returns nested story comments by id </b>&nbsp;<small>(returns XML or JSON)</small><br /><br />
+ <table>
+ <tr>
+ <td>URL:</td>
+ <td>http://hndroidapi.appspot.com/nestedcomments/format/<em>&lt;format&gt;</em>/id/<em>&lt;id&gt;</em></td>
+ </tr>
+ <tr>
+ <td>Story Id:</td>
+ <td><input type="text" id="nestedcomments-pageid" name="nestedcomments-pageid" />&nbsp;<small>(e.g. 3423232)</small></td>
+ </tr>
+ <tr>
+ <td>Format:</td>
+ <td><input type="radio" name="nestedcomments-format" value="json" checked='checked'/>JSON&nbsp;<input type="radio" name="nestedcomments-format" value="xml"/>XML</td>
+ </tr>
+ <tr>
+ <td colspan='2'><input type="button" value=" Test " onclick="getNestedComments()" /></td>
+ </tr>
+ </table>
+ <br />
+</fieldset>
+
+<hr >
<a name="latest"></a>
<h2>Latest: Simple API</h2>
<fieldset>
@@ -383,36 +441,13 @@
</table>
<br />
</fieldset>
-<hr >
-<a name="comments"></a>
-<h2>Comments by Story ID</h2>
-<fieldset>
- <b>Returns story comments by id </b>&nbsp;<small>(returns XML or JSON)</small><br /><br />
- <table>
- <tr>
- <td>URL:</td>
- <td>http://hndroidapi.appspot.com/comments/format/<em>&lt;format&gt;</em>/id/<em>&lt;id&gt;</em></td>
- </tr>
- <tr>
- <td>Story Id:</td>
- <td><input type="text" id="comments-pageid" name="comments-pageid" />&nbsp;<small>(e.g. 3423232)</small></td>
- </tr>
- <tr>
- <td>Format:</td>
- <td><input type="radio" name="comments-format" value="json" checked='checked'/>JSON&nbsp;<input type="radio" name="comments-format" value="xml"/>XML</td>
- </tr>
- <tr>
- <td colspan='2'><input type="button" value=" Test " onclick="getComments()" /></td>
- </tr>
- </table>
- <br />
-</fieldset>
+
</form>
</div>
<hr />
<p>
- Built by <a href="http://glebche.appspot.com">Gleb Popov</a>. Last updated: {{last_updated}}.
+ <strong>Author</strong>: <a href="http://glebche.appspot.com">Gleb Popov</a>. <strong>Credits</strong>: Suan Aik Yeo (Nested Comments API), Eric Kigathi (backend server support). Last updated: {{last_updated}}.
</p>
<script type="text/javascript">
Please sign in to comment.
Something went wrong with that request. Please try again.