def loadGenFiles(cls): log.web("Loading generated files for",cls.__name__) cls.genFiles = [] for method in dir(cls): #We just go through all the methods available in the class if method.startswith("do_"): function = getattr(cls, method) if hasattr(function, "_supportedExtensions"): extList = function._supportedExtensions else: extList = ["html",] for ext in extList: #Adds all the pages to look out for #These should look like "do_page" --> "page.html" #The "if ext else"... because we can have no extension as well cls.genFiles.append(method.replace("do_","",1)+("." if ext else "")+ext) log.web("Files available:", cls.genFiles)
def main(): """Initialize All Modules""" tokenList = Files.getTokenList() #[0] should be mine, and [1] should be my alt for group creation log.debug("Tokens:",tokenList) #Just my user id and token put = ("27094908", tokenList[0]) #Totally Not The NSA Token Groups.Group.overlord = tokenList[1] #Just things log.network.debug.disable() #Suppress the return value of every message #log.command.low.enable() #For going through all the commands every time we get a command #log.user.low.enable() #For going through all the users every time we search for a user if Events.IS_TESTING: log.save.low.enable() #First load all the groups log.info("========== PRE-INIT (LOAD) ==========") toLoadList = [] for folder in Files.getDirsInDir(): if "Group " in folder: #If it a folder containing a group to load number = int(folder.split(" ")[-1]) obj = (number, folder,) #Tuple of number and folder name flag = True for i in range(len(toLoadList)): #Sort the list if number < toLoadList[i][0]: toLoadList.insert(i, obj) flag = False break if flag: #If did not insert anywhere else toLoadList.append(obj) #Loadsd the groups guarenteed in order for group in toLoadList: Groups.loadGroup(group[1]) log.info("Groups: ", Groups.getSortedList()) #Do init and post-init log.info("========== INIT ==========") for group in list(Groups.getSortedList()): group.init() ### Named groups should be made after INIT to avoid duplicated initial users testGroup = makeNamedGroup(1, "23199161", put) toriGroup = makeNamedGroup(15, "23317842", put, "DLARulez") groupFam = makeNamedGroup(2, "13972393", put, "easier") groupOldRocket = makeNamedGroup(10, "26730422", put, "password") rocketMainGroup = makeCollective(20, "33057510", put) electronicsGroup = makeCollector(21, "33057523", put, rocketMainGroup) designAndMGroup = makeCollector(22, "33058451", put, rocketMainGroup) propulsionGroup = makeCollector(23, "33058488", put, rocketMainGroup) civGroup = makeCollective(30, "36614847", put, classType = Groups.Group) #Just a collective because I'm lazy in properly naming things. Is a normal group try: #This is so we can have our finally block remove any extra threads in case of error log.info("========== POST-INIT ==========") for group in list(Groups.getSortedList()): try: group.postInit() except AssertionError: pass log.info("========== GROUP CLEANUP ==========") deletionList = Groups.getSortedList() deletionList.reverse() for i in deletionList.copy(): if i.markedForDeletion: log.info("Deleting group", i) i.deleteSelf() del i del deletionList #try: def postEarlyMorningFact(): joke = Jokes.funFacts.getJoke() if type(joke) == tuple: return Jokes.funFacts._postJoke(groupFam, ("Oh boy 3 A.M.!\n"+joke[0], joke[1])) return Jokes.funFacts._postJoke(groupFam, "Oh boy 3 A.M.!\n" + joke) def updateAllMsgLists(): for searcher in MsgSearch._searcherList: #We could also probably get from all active groups instead of the searcher list searcher.GenerateCache() def postCivReminder(): civGroup.handler.write("Don't forget to do your civ turn!") server = Server(('', Network.SERVER_CONNECTION_PORT), ServerHandler) #Update things for the groups every day at 5 a.m. log.info("Starting daily triggers") updaterDaily = Events.DailyUpdater( time(5, 0), Groups.groupDailyDuties) updaterWebsite = Events.DailyUpdater( time(4,58), Website.securityPurge) #Just do this seperately earlyMorningFacts = Events.DailyUpdater( time(3, 0), postEarlyMorningFact) monthlyMsgRefresh = Events.WeeklyUpdater(time(5,10), Events.WEEKDAY.SATURDAY, updateAllMsgLists, unitDifference = 4) #Once a month dailyCivReminder = Events.DailyUpdater( time(15,0), postCivReminder) log.info("========== BEGINNING SERVER RECEIVING ==========") try: log.web("Starting server on port",Network.SERVER_CONNECTION_PORT) server.serve_forever() except KeyboardInterrupt: pass if server.exitValue != None: #Value of none means exited due to KeyboardInterrupt or something else log.info("Server shutting down from user input") if server.exitValue: #Exit value true means restart return 0; else: #False means shutdown raise AssertionError("Signal to main that we are done") #TESTING CODE: if Events.IS_TESTING: import traceback while True: print("> ", end = "") try: statement = input() if statement.lower() == "quit": break elif "=" in statement: exec(statement) else: print(eval(statement)) except Exception as e: if isinstance(e, KeyboardInterrupt) or isinstance(e, EOFError): from os import _exit _exit(0) #Screw this crap, just get out of here. It's only for testing else: traceback.print_exc() raise AssertionError("Signal to main that we are done") #We need to kill all threads before exiting finally: Events.stopAllTimers() Events.SyncSave().saveAll(final = True)
def do_searchResults(self): log.web.debug("Starting search results") toSend = self.loadFile(self.PAGE_DEF_GEN) group = self.groupObj if group: numFound = 0 maxResults = 250 numAround = 2 #Number on either side of found nameLimit = 20 #Characters for a group name #We are going to be yielding data so we do not need to buffer if 'query' in self.params: query = self.params["query"][0] permissiveSearch = "strict" in self.params and (self.params["strict"][0] == "false") log.web("Starting search results for query: ",query) #This will be copied and modified by every search result mainMessage = """<tr class="SearchContainer {subclass}" id="{resultNum}{position}"> <td class="SearchLeft"><div style="text-align:center;padding=0px;margin=px">{userName}</div>{groupName}<br>{date}</td> <td class="SearchPicture"><a href="searchResults.html?query={text}&strict=true"><img class = "SearchPicture" src="{avatar}"></a></td> <td class="SearchRight"><div class="SearchResults"> {text} {image} </div></td> </tr>\n""" pictureText = """<br><img width=75% style="padding-top:10px" src="{}">""" #Send top part of html self.writeText(toSend.split(self.STR_CONTENT)[0].replace(self.STR_TITLE, "Search Results")) #Write initial scripts self.writeText('''<script src="util.js"></script> <script src="searchClickScript.js"></script> <form action="search.html"><button style="display:inline-block;width:100%;">Do another search!</button></form> <p>Your Search: {query}</p><br> <table border="5" width="100%" sytle="table-layout:fixed">'''.format(query = query)) i=-1 searcher = MsgSearch.getSearcher(group) for message in searcher: i += 1 #Iterates through all words of prompt if permissive, otherwise through a tuple containing only the query for word in (re.split("\W+", query) if permissiveSearch else (query,)): #Searches for the word(s) in each message (text can be None) if message.text and re.search(re.escape(word), message.text, re.IGNORECASE): #And the message and surrounding ones #This directly sends each search result as its generated lowerBound = max(i-numAround, 0) upperBound = min(i+numAround+1, len(searcher)-1) index = lowerBound #Index starts at this bound, and increases to upperBound-1 for message in searcher[lowerBound : upperBound]: #Get user's name (or system) for display userName = message.getUserString() if message.isUser(): user = group.users.getUserFromID(message.user_id) if user: userName = user.getName() #Just directly writes this part as soon as its done self.writeText(mainMessage.format(\ #Only the main result should be visible subclass = ("" if index == i else "Hidden"), \ #The result number on the page resultNum = str(numFound), \ #If not the initial value, sets the index to the difference in index and lower bound, then subtracts another if it is after the intitial value position = ("" if index == i else (" "+str(index-lowerBound-int(index >= i)))), \ #User's name or "calendar" or "system" or whatever userName = userName, #The group's name (shortened) groupName = (group.getName()[:nameLimit] + ("..." if len(group.getName()) >= nameLimit else "")), #Add date message was sent date = datetime.date.fromtimestamp(int(message["created_at"])).strftime("%m/%d/%y"), \ #The user's avatar url (if none it will put the icon of it) avatar = (message['avatar_url'] or self.PAGE_ICON), \ #The actual message text text = (message['text'] or "").replace("\n","<br>"), \ #The optional image (if there is one) image = (pictureText.format(message['attachments'][0]['url']) if (len(message['attachments']) > 0 and message['attachments'][0]['type'] == "image") else "") \ )) index += 1 #Increment index numFound += 1 #Add that we have found another matched break #Don't want to generate multiple results from the same message if numFound > maxResults: #So people don't break the server break self.writeText("</table>") if numFound == 0: self.writeText("No messages matched your search") if numFound > maxResults: self.writeText("Too Many Results...") #Send bottom part of html self.writeText(toSend.split(self.STR_CONTENT, 1)[1]) #Split with max split size of 1 self.sendResponse() #Then send all the data else: self.sendError("No query found in search!") raise RuntimeError("No query in search") #Gets picked up to send error