def getHomeScreen(self, numberOfTopics, numberOfSubjects): topicDictsAsJson = Hermes.getHomeScreen(numberOfTopics, numberOfSubjects) if topicDictsAsJson.__len__() == 0: return "[]" else: return ujson.dumps(topicDictsAsJson)
def getSinglePost(self, fingerprint): post = Hermes.fetchSinglePost(fingerprint) if post.__len__() == 0: return "[]" else: # Post[0] because it's all() and not one() in SQLAlchemy, otherwise when not found it # throws exceptions in my face. return ujson.dumps(post[0].asDict(), ensure_ascii=False)
def getDirectDescendantPosts(self, fingerprint): posts = Hermes.fetchDirectDescendantPosts(fingerprint) returnList = [] if posts.__len__() == 0: return "[]" else: for post in posts: postJSON = ujson.dumps(post.asDict(), ensure_ascii=False) returnList.append(postJSON) return ujson.dumps(returnList, ensure_ascii=False)
def getReplies(self): posts = Hermes.getReplies() returnList = [] if posts.__len__() == 0: return "[]" else: for post in posts: postJSON = ujson.dumps(post.asDict(), ensure_ascii=False) returnList.append(postJSON) return ujson.dumps(returnList, ensure_ascii=False)
def getSpecificDepthPosts(self, fingerprint, depth): posts = Hermes.fetchDescendantPosts(fingerprint, depth) returnList = [] if posts.__len__() == 1: return "[]" else: for post in posts: postJSON = ujson.dumps(post[0].asDict(), ensure_ascii=False) returnList.append(postJSON) return ujson.dumps(returnList, ensure_ascii=False)
def getSubjects(self, fingerprint, daysToSubtract): posts = Hermes.getSubjects(fingerprint, daysToSubtract) returnList = [] if posts.__len__() == 0: return "[]" else: for post in posts: # asDict only converts to dict the values in models table. add the rest by hand. postDict = post.asDict() postDict['FirstPostBody'] = post.FirstPostBody postDict['FirstPostOwner'] = post.FirstPostOwner postJSON = ujson.dumps(postDict, ensure_ascii=False) returnList.append(postJSON) return ujson.dumps(returnList, ensure_ascii=False)
def createSignedPost(self, postSubject, postText, parentPostFingerprint, ownerFingerprint): return Hermes.createSignedPost(postSubject, postText, parentPostFingerprint, ownerFingerprint)
def createTopic(self, topicName): return Hermes.createTopic(topicName)
def getLastConnectionTime(self): return ujson.dumps(Hermes.getLastConnectionTime())
def getUnregisteredUserPosts(self, name): posts = Hermes.getUnregisteredUserPosts(name) return multiJsonify(posts)
def countReplies(self): return Hermes.countReplies()
def getSubjectCounts(self, days, fingerprintsListAsJSON): return ujson.dumps(Hermes.multiCountDirectDescendantPostsWithTimespan( days, ujson.loads(fingerprintsListAsJSON)), ensure_ascii=False)
def getTopmostComment(self, fingerprint): post = Hermes.getTopmostComment(fingerprint) if post is None: return "[]" else: return ujson.dumps(post.asDict(), ensure_ascii=False)
def markAllRepliesAsRead(self): return Hermes.markAllRepliesAsRead()
def savePost(self, fingerprint): return Hermes.savePost(fingerprint)
def votePost(self, fingerprint, voteDirection): return Hermes.votePost(fingerprint, voteDirection)
def createPost(self, postSubject, postText, parentPostFingerprint, ownerUsername, postLanguage): return Hermes.createPost(postSubject, postText, parentPostFingerprint, ownerUsername, postLanguage)
def writeUserProfile(self, userProfileInJSON): # I need to do some stuff here to ensure data in json matches the one in profile. return Hermes.writeUserProfile(userProfileInJSON)
def getUserProfile(self): if Hermes.readUserProfile() != '': return Hermes.readUserProfile() else: return '{}'
def countConnectedNodes(self): return Hermes.countConnectedNodes()
def getUser(self, fingerprint): user = Hermes.fetchUser(fingerprint) return user
def getParentSubjectOfGivenPost(self, fingerprint): return multiJsonify(Hermes.getParentSubjectOfGivenPost(fingerprint))
def countSubjects(self): return Hermes.countSubjects()
def main(): global reactor from twisted.internet import reactor print('Spawning the networking daemon...') # Spawn the networking daemon. from InputOutput import interprocessChildProt from ampoule_aether import pool from InputOutput import interprocessParentProt from ampoule_aether import main as ampouleMain if FROZEN: procStarter = ampouleMain.ProcessStarter() else: procStarter = ampouleMain.ProcessStarter( bootstrap=interprocessChildProt.childBootstrap) global pp pp = pool.ProcessPool(interprocessChildProt.NetworkingProcessProtocol, ampParent=interprocessParentProt.MainProcessProtocol, starter=procStarter, recycleAfter=0, min=1, max=1) pp.start() pp.ampParent.processPool = pp # Self referential much? # Networking daemon spawnage ends here. print('Networking daemon spawned.') hermes = Hermes.Hermes(pp) charon = Charon(hermes) view = AetherMainWindow(charon, reactor, baseurl, app) if PLATFORM == 'OSX' or PLATFORM == 'WIN': trayIcon = SystemTrayIcon(BASEDIR, app, view) # trayIcon.protInstance = protInstance # protInstance.trayIcon = trayIcon ef = ModifierEventFilter() app.view = view ef.view = view view.pp = pp if PLATFORM == 'OSX' or PLATFORM == 'WIN': app.trayIcon = trayIcon view.trayIcon = trayIcon ef.trayIcon = trayIcon charon.trayIcon = trayIcon trayIcon.webView = view trayIcon.show() app.installEventFilter(ef) # Attach the items to the parent protocol, so it can react on the events arriving from networking daemon. pp.ampParent.Hermes = hermes if PLATFORM == 'OSX' or PLATFORM == 'WIN': pp.ampParent.trayIcon = trayIcon pp.ampParent.JSContext = view.JSContext if globals.userProfile.get('debugDetails', 'enableWebkitInspector'): from PyQt5.QtWebKit import QWebSettings QWebSettings.globalSettings().setAttribute( QWebSettings.DeveloperExtrasEnabled, True) inspect = QWebInspector() inspect.resize(1450, 300) inspect.move(0, 0) inspect.setPage(view.webView.page()) view.setContextMenuPolicy(Qt.DefaultContextMenu) inspect.show() splash.finish(view) if globals.APP_STARTED_AT_SYSTEM_STARTUP: if PLATFORM == 'LNX': # Because there is no tray icon on Linux, app starts minimised ( (-) state). view.showMinimized() elif PLATFORM == 'OSX' or PLATFORM == 'WIN': pass # Do nothing, there is already a tray icon in place. else: # If not started at boot view.show() def checkForUpdates(): # One catch, any result available out of this will only be visible after next boot of the app. d = getPage('http://www.getaether.net/updatecheck') def processReceivedVersion(reply): if int(reply[:3]) > AETHER_VERSION: globals.userProfile.set('machineDetails', 'updateAvailable', True) print( 'There is an update available, local version is %d and gathered version is %s.' % (AETHER_VERSION, reply)) else: globals.userProfile.set('machineDetails', 'updateAvailable', False) print('There is no update available') return d.addCallback(processReceivedVersion) if globals.userProfile.get('machineDetails', 'checkForUpdates'): d = checkForUpdates() d.addErrback( print, 'Checking for updates failed. Either the server is down, or the internet connection is not available.' ) def setPublicIPAddress(): # For privacy reasons, this can be disabled by setting 'allowPublicIPLookup' to false at your user profile json. # The only use case for this is to show you your IP address in the settings, so you can give your IP address # and port to your friend to use you as the bootstrap node. If you can read this, you don't need that. Disable. data = str(urlopen('http://checkip.dyndns.com/').read()) result = re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search( data).group(1) globals.userProfile.set('machineDetails', 'externalIP', result) print('Public IP of this machine is %s' % result) return True if globals.userProfile.get('machineDetails', 'allowPublicIPLookup'): d2 = threads.deferToThread(setPublicIPAddress) # d2.addErrback(print, 'The public IP address could not be found. The internet connection is not available.') reactor.run()
def countUppermostTopics(self): return Hermes.countTopics()
def getSubjectCounts(self, days, fingerprintsListAsJSON): return ujson.dumps(Hermes.multiCountDirectDescendantPostsWithTimespan(days, ujson.loads( fingerprintsListAsJSON)), ensure_ascii=False)
def countAllDescendantPosts(self, fingerprint): count = Hermes.countAllDescendantPosts(fingerprint) return count
def main(reactorString, ampChildPath): #def main(): from twisted.internet import reactor, stdio from twisted.python import reflect, runtime #ampChild = reflect.namedAny(ampChildPath) #protInstance = ampChild(*sys.argv[1:-2]) # This is how you reach the prot from here. protInstance = '' from twisted.internet import reactor # this is actually used, ignore the warning. hermes = Hermes.Hermes(protInstance) charon = Charon(hermes) view = AetherMainWindow(charon, reactor, baseurl, protInstance) trayIcon = SystemTrayIcon(basedir, app, view) trayIcon.protInstance = protInstance #protInstance.trayIcon = trayIcon ef = ModifierEventFilter() app.view = view ef.view = view app.trayIcon = trayIcon view.trayIcon = trayIcon ef.trayIcon = trayIcon charon.trayIcon = trayIcon trayIcon.webView = view app.installEventFilter(ef) trayIcon.show() #FIXME before package enableWebkitInspector = False if enableWebkitInspector is True: from PyQt5.QtWebKit import QWebSettings QWebSettings.globalSettings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) inspect = QWebInspector() inspect.resize(1450, 300) inspect.move(0,0) inspect.setPage(view.webView.page()) view.setContextMenuPolicy(Qt.DefaultContextMenu) inspect.show() splash.finish(view) if not globals.appStartedAtBoot: view.show() trayIcon.toggleVisibilityMenuItem.setText('Hide Aether') if runtime.platform.isWindows(): stdio.StandardIO(protInstance) else: stdio.StandardIO(protInstance, 3, 4) #enter = getattr(ampChild, '__enter__', None) # if enter is not None: # enter() # try: # reactor.run() # except: # if enter is not None: # info = sys.exc_info() # if not ampChild.__exit__(*info): # raise # else: # raise # else: # if enter is not None: # ampChild.__exit__(None, None, None) reactor.run()