diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b4ef163 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Compiled python modules. +*.pyc + +# Distribution / packaging +bin/ +build/ +develop-eggs/ +dist/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt \ No newline at end of file diff --git a/README.md b/README.md index a17c434..35055dc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ because nw doesn't support AppIndicators yet. ##To-Do - Auto Start -- Convert to a Python Module - Try to convert right click to comments link ##Author Information diff --git a/__main__.py b/__main__.py index 117faa6..10e95b2 100644 --- a/__main__.py +++ b/__main__.py @@ -17,6 +17,8 @@ except ImportError: class HackerNewsApp: def __init__(self): + + print "Loading HackerTray" #Load the database home = expanduser("~") with open(home+'/.hackertray.json', 'a+') as content_file: @@ -90,7 +92,7 @@ class HackerNewsApp: '''Refreshes the menu ''' def refresh(self, widget=None, data=None): - data = reversed(getHomePage()[0:20]); + data = reversed(self.getHomePage()[0:20]); #Remove all the current stories for i in self.menu.get_children(): if(hasattr(i,'url')): @@ -101,15 +103,11 @@ class HackerNewsApp: #Call every 5 minutes gtk.timeout_add(5*60*1000, self.refresh) -'''Returns all the news stories from homepage''' -def getHomePage(): - r = requests.get('https://node-hnapi.herokuapp.com/news') - return r.json() + '''Returns all the news stories from homepage''' + def getHomePage(): + r = requests.get('https://node-hnapi.herokuapp.com/news') + return r.json() -def main(): +def main() gtk.main() - return 0 - -if __name__ == "__main__": - indicator = HackerNewsApp() - main() \ No newline at end of file + return 0 \ No newline at end of file diff --git a/hackertray/__init__.py b/hackertray/__init__.py new file mode 100644 index 0000000..117faa6 --- /dev/null +++ b/hackertray/__init__.py @@ -0,0 +1,115 @@ +#!/usr/bin/python + +import pygtk +pygtk.require('2.0') +import gtk + +import requests +import webbrowser +import json + +from os.path import expanduser + +try: + import appindicator +except ImportError: + import appindicator_replacement as appindicator + +class HackerNewsApp: + def __init__(self): + #Load the database + home = expanduser("~") + with open(home+'/.hackertray.json', 'a+') as content_file: + content_file.seek(0) + content = content_file.read() + try: + self.db = set(json.loads(content)) + except: + self.db = set() + + # create an indicator applet + self.ind = appindicator.Indicator ("Hacker Tray", "hacker-tray", appindicator.CATEGORY_APPLICATION_STATUS) + self.ind.set_status (appindicator.STATUS_ACTIVE) + self.ind.set_label("Y") + + # create a menu + self.menu = gtk.Menu() + + # create items for the menu - refresh, quit and a separator + menuSeparator = gtk.SeparatorMenuItem() + menuSeparator.show() + self.menu.append(menuSeparator) + + btnRefresh = gtk.MenuItem("Refresh") + btnRefresh.show() + btnRefresh.connect("activate", self.refresh) + self.menu.append(btnRefresh) + + btnQuit = gtk.MenuItem("Quit") + btnQuit.show() + btnQuit.connect("activate", self.quit) + self.menu.append(btnQuit) + + self.menu.show() + + self.ind.set_menu(self.menu) + self.refresh() + + ''' Handler for the quit button''' + #ToDo: Handle keyboard interrupt properly + def quit(self, widget, data=None): + l=list(self.db) + home = expanduser("~") + #truncate the file + file = open(home+'/.hackertray.json', 'w+') + file.write(json.dumps(l)) + gtk.main_quit() + + '''Opens the link in the web browser''' + def open(self, widget, event=None, data=None): + #We disconnect and reconnect the event in case we have + #to set it to active and we don't want the signal to be processed + if(widget.get_active() == False): + widget.disconnect(widget.signal_id) + widget.set_active(True) + widget.signal_id = widget.connect('activate', self.open) + self.db.add(widget.item_id) + webbrowser.open(widget.url) + + '''Adds an item to the menu''' + def addItem(self, item): + if(item['points'] == 0 or item['points'] == None): #This is in the case of YC Job Postings, which we skip + return + i = gtk.CheckMenuItem("("+str(item['points']).zfill(3)+"/"+str(item['comments_count']).zfill(3)+") "+item['title']) + i.set_active(item['id'] in self.db) + i.url = item['url'] + i.signal_id = i.connect('activate', self.open) + i.item_id = item['id'] + self.menu.prepend(i) + i.show() + + '''Refreshes the menu ''' + def refresh(self, widget=None, data=None): + data = reversed(getHomePage()[0:20]); + #Remove all the current stories + for i in self.menu.get_children(): + if(hasattr(i,'url')): + self.menu.remove(i) + #Add back all the refreshed news + for i in data: + self.addItem(i) + #Call every 5 minutes + gtk.timeout_add(5*60*1000, self.refresh) + +'''Returns all the news stories from homepage''' +def getHomePage(): + r = requests.get('https://node-hnapi.herokuapp.com/news') + return r.json() + +def main(): + gtk.main() + return 0 + +if __name__ == "__main__": + indicator = HackerNewsApp() + main() \ No newline at end of file diff --git a/appindicator_replacement.py b/hackertray/appindicator_replacement.py similarity index 100% rename from appindicator_replacement.py rename to hackertray/appindicator_replacement.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..6ad0e7c --- /dev/null +++ b/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + +setup(name='hackertray', + version='1.1', + description='Hacker News app that sits in your System Tray', + url='http://github.com/captn3m0/hackertray', + author='Abhay Rana', + author_email='me@captnemo.in', + license='MIT', + packages=['hackertray'], + install_requires=[ + 'requests', + ], + scripts=['bin/hackertray'], + zip_safe=False) \ No newline at end of file