def load_relation(filename, defname=None): if not os.path.isfile(filename): print (colorize( "%s is not a file" % filename, ERROR_COLOR), file=sys.stderr) return None f = filename.split('/') if defname == None: defname = f[len(f) - 1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] if not rtypes.is_valid_relation_name(defname): print (colorize( "%s is not a valid relation name" % defname, ERROR_COLOR), file=sys.stderr) return try: relations[defname] = relation.relation(filename) completer.add_completion(defname) printtty(colorize("Loaded relation %s" % defname, 0x00ff00)) return defname except Exception as e: print (colorize(e, ERROR_COLOR), file=sys.stderr) return None
def _run_multiline(self): query = self.ui.txtMultiQuery.toPlainText() self.settings.setValue('multiline/query', query) queries = query.split('\n') for query in queries: if query.strip() == '': continue parts = query.split('=', 1) parts[0] = parts[0].strip() if len(parts) > 1 and rtypes.is_valid_relation_name(parts[0].strip()): relname = parts[0].strip() query = parts[1] else: relname = 'last_' try: expr = parser.parse(query) print ('%s <- %s' % (relname, expr)) result = eval(expr, self.relations) self.relations[relname] = result except Exception as e: print(str(e)) QtWidgets.QMessageBox.information(None, QtWidgets.QApplication.translate("Form", "Error"), u"%s\n%s" % (QtWidgets.QApplication.translate("Form", "Check your query!"), str(e))) break self.updateRelations() # update the list self.selectedRelation = result self.showRelation(self.selectedRelation)
def newRelation(self): import creator result = creator.edit_relation() if result == None: return res = QtGui.QInputDialog.getText( self, QtGui.QApplication.translate("Form", "New relation"), QtGui.QApplication.translate( "Form", "Insert the name for the new relation"), QtGui.QLineEdit.Normal, '') if res[1] == False or len(res[0]) == 0: return # Patch provided by Angelo 'Havoc' Puglisi name = compatibility.get_py_str(res[0]) if not rtypes.is_valid_relation_name(name): r = QtGui.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Error"), r) return try: self.relations[name] = result except Exception, e: print e QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__str__())) return
def execute(self): '''Executes the query''' query = compatibility.get_py_str(self.ui.txtQuery.text()) res_rel = compatibility.get_py_str( self.ui.txtResult.text()) # result relation's name if not rtypes.is_valid_relation_name(res_rel): QtGui.QMessageBox.information(self, QtGui.QApplication.translate( "Form", "Error"), QtGui.QApplication.translate("Form", "Wrong name for destination relation.")) return try: # Converting string to utf8 and then from qstring to normal string expr = parser.parse(query) # Converting expression to python code print query, "-->", expr # Printing debug result = eval(expr, self.relations) # Evaluating the expression self.relations[ res_rel] = result # Add the relation to the dictionary self.updateRelations() # update the list self.selectedRelation = result self.showRelation(self.selectedRelation) # Show the result in the table except Exception, e: #print e.__unicode__() QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), u"%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__unicode__())) return
def loadRelation(self, filenames=None): '''Loads a relation. Without parameters it will ask the user which relation to load, otherwise it will load filename, giving it name. It shouldn't be called giving filename but not giving name.''' # Asking for file to load if not filenames: f = QtWidgets.QFileDialog.getOpenFileNames(self, QtWidgets.QApplication.translate( "Form", "Load Relation"), "", QtWidgets.QApplication.translate("Form", "Relations (*.csv);;Text Files (*.txt);;All Files (*)")) filenames = f[0] for f in filenames: # Default relation's name name = os.path.basename(f).lower() if len(name) == 0: return if (name.endswith(".csv")): # removes the extension name = name[:-4] if not rtypes.is_valid_relation_name(name): name = self.promptRelationName() if name is None: continue try: self.relations[name] = relation.relation(f) except Exception as e: print (e) QtWidgets.QMessageBox.information(None, QtWidgets.QApplication.translate("Form", "Error"), "%s\n%s" % (QtWidgets.QApplication.translate("Form", "Check your query!"), e.__str__())) continue self.updateRelations()
def load_relation(filename: str, defname:Optional[str]=None) -> Optional[str]: ''' Loads a relation into the set. Defname is the given name to the relation. Returns the name to the relation, or None if it was not loaded. ''' if not os.path.isfile(filename): print(colorize( "%s is not a file" % filename, ERROR_COLOR), file=sys.stderr) return None if defname is None: f = filename.split('/') defname = f[-1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] if not rtypes.is_valid_relation_name(defname): print(colorize( "%s is not a valid relation name" % defname, ERROR_COLOR), file=sys.stderr) return None try: relations[defname] = relation.relation(filename) completer.add_completion(defname) printtty(colorize("Loaded relation %s" % defname, COLOR_GREEN)) return defname except Exception as e: print(colorize(str(e), ERROR_COLOR), file=sys.stderr) return None
def load_relation(filename: str, defname: Optional[str] = None) -> Optional[str]: ''' Loads a relation into the set. Defname is the given name to the relation. Returns the name to the relation, or None if it was not loaded. ''' if not os.path.isfile(filename): print(colorize("%s is not a file" % filename, ERROR_COLOR), file=sys.stderr) return None if defname is None: f = filename.split('/') defname = f[-1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] if not rtypes.is_valid_relation_name(defname): print(colorize("%s is not a valid relation name" % defname, ERROR_COLOR), file=sys.stderr) return None try: relations[defname] = relation.relation(filename) completer.add_completion(defname) printtty(colorize("Loaded relation %s" % defname, COLOR_GREEN)) return defname except Exception as e: print(colorize(str(e), ERROR_COLOR), file=sys.stderr) return None
def parse_tokens(expression: List[Union[list, str]]) -> Node: '''Generates the tree from the tokenized expression If no expression is specified then it will create an empty node''' # If the list contains only a list, it will consider the lower level list. # This will allow things like ((((((a))))) to work while len(expression) == 1 and isinstance(expression[0], list): expression = expression[0] if len(expression) == 0: raise ParserException(_('Failed to parse empty expression')) # The list contains only 1 string. Means it is the name of a relation if len(expression) == 1: assert isinstance(expression[0], str) if not rtypes.is_valid_relation_name(expression[0]): raise ParserException( f'{expression[0]!r} is not a valid relation name') return Variable(expression[0]) #FIXME Move validation in the object # Expression from right to left, searching for binary operators # this means that binary operators have lesser priority than # unary operators. # It finds the operator with lesser priority, uses it as root of this # (sub)tree using everything on its left as left parameter (so building # a left subtree with the part of the list located on left) and doing # the same on right. # Since it searches for strings, and expressions into parenthesis are # within sub-lists, they won't be found here, ensuring that they will # have highest priority. for i in range(len(expression) - 1, -1, -1): if expression[i] in b_operators: # Binary operator if len(expression[:i]) == 0: raise ParserException( _('Expected left operand for %s') % repr(expression[i])) if len(expression[i + 1:]) == 0: raise ParserException( _('Expected right operand for %s') % repr(expression[i])) return Binary(expression[i], parse_tokens(expression[:i]), parse_tokens(expression[i + 1:])) # type: ignore '''Searches for unary operators, parsing from right to left''' for i in range(len(expression)): if expression[i] in u_operators: # Unary operator if len(expression) <= i + 2: raise ParserException( _('Expected more tokens in %s') % repr(expression[i])) elif len(expression) > i + 3: raise ParserException( _('Too many tokens in %s') % repr(expression[i])) return Unary( expression[i], # type: ignore prop=expression[1 + i].strip(), # type: ignore child=parse_tokens(expression[2 + i]) # type: ignore ) raise ParserException(_('Parse error on %s') % repr(expression))
def execute(self, query, relname='last_'): '''Executes a query, returns the result and if relname is not None, adds the result to the dictionary, with the name given in relname.''' if not is_valid_relation_name(relname): raise Exception('Invalid name for destination relation') expr = parser.parse(query) result = expr(self.relations) self.relations[relname] = result return result
def execute(self, query: str, relname: str = 'last_') -> Relation: '''Executes a query, returns the result and if relname is not None, adds the result to the dictionary, with the name given in relname.''' if not is_valid_relation_name(relname): raise Exception(_('Invalid name for destination relation')) expr = parser.parse(query) result = expr(self.relations) self.relations[relname] = result return result
def loadRelation(self, filename=None, name=None): '''Loads a relation. Without parameters it will ask the user which relation to load, otherwise it will load filename, giving it name. It shouldn't be called giving filename but not giving name.''' #Asking for file to load if filename == None: filename = QtGui.QFileDialog.getOpenFileName( self, QtGui.QApplication.translate("Form", "Load Relation"), "", QtGui.QApplication.translate( "Form", "Relations (*.csv);;Text Files (*.txt);;All Files (*)")) filename = compatibility.get_filename(filename) #Default relation's name f = filename.split('/') #Split the full path defname = f[len(f) - 1].lower() #Takes only the lowercase filename if len(defname) == 0: return if (defname.endswith(".csv")): #removes the extension defname = defname[:-4] if name == None: #Prompt dialog to insert name for the relation res = QtGui.QInputDialog.getText( self, QtGui.QApplication.translate("Form", "New relation"), QtGui.QApplication.translate( "Form", "Insert the name for the new relation"), QtGui.QLineEdit.Normal, defname) if res[1] == False or len(res[0]) == 0: return #Patch provided by Angelo 'Havoc' Puglisi name = compatibility.get_py_str(res[0]) if not rtypes.is_valid_relation_name(name): r = QtGui.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Error"), r) return try: self.relations[name] = relation.relation(filename) except Exception, e: print e QtGui.QMessageBox.information( None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate( "Form", "Check your query!"), e.__str__())) return
def promptRelationName(self): while True: res = QtWidgets.QInputDialog.getText( self, _("New relation"), _("Insert the name for the new relation"), QtWidgets.QLineEdit.Normal, '') if res[1] == False: # or len(res[0]) == 0: return None name = res[0] if not rtypes.is_valid_relation_name(name): QtWidgets.QMessageBox.information( self, _("Error"), _('Wrong name for destination relation: {name}.')) continue return name
def split_query(query: str, default_name='last_') -> Tuple[str, str]: ''' Accepts a query which might have an initial value assignment a = query Returns a tuple with result_name, query ''' sq = query.split('=', 1) if len(sq) == 2 and is_valid_relation_name(sq[0].strip()): default_name = sq[0].strip() query = sq[1].strip() return default_name, query
def split_query(query, default_name='last_'): ''' Accepts a query which might have an initial value assignment a = query Returns a tuple with result_name, query ''' sq = query.split('=', 1) if len(sq) == 2 and is_valid_relation_name(sq[0].strip()): default_name = sq[0].strip() query = sq[1].strip() return default_name, query
def promptRelationName(self): while True: res = QtWidgets.QInputDialog.getText( self, QtWidgets.QApplication.translate("Form", "New relation"), QtWidgets.QApplication.translate("Form", "Insert the name for the new relation"), QtWidgets.QLineEdit.Normal, "", ) if res[1] == False: # or len(res[0]) == 0: return None name = res[0] if not rtypes.is_valid_relation_name(name): r = QtWidgets.QApplication.translate("Form", str("Wrong name for destination relation: %s." % name)) QtWidgets.QMessageBox.information(self, QtWidgets.QApplication.translate("Form", "Error"), r) continue return name
def exec_query(command): '''This function executes a query and prints the result on the screen if the command terminates with ";" the result will not be printed ''' #If it terminates with ; doesn't print the result if command.endswith(';'): command = command[:-1] printrel = False else: printrel = True # RZ avisamos que estamos enviando un utf-8 para que no se complique command = command.encode('utf-8') #Performs replacements for weird operators command = replacements(command) #Finds the name in where to save the query parts = command.split('=', 1) if len(parts) > 1 and rtypes.is_valid_relation_name(parts[0]): relname = parts[0] query = parts[1] else: relname = 'last_' query = command query = unicode(query, 'utf-8') #Execute query try: pyquery = parser.parse(query) result = eval(pyquery, relations) out = "" #out = colored("-> query: %s" % pyquery, 'green') if printrel: out += "" out += str(result) relations[relname] = result completer.add_completion(relname) return out except Exception, e: print e return colored(e, 'red')
def loadRelation(self, filename=None, name=None): '''Loads a relation. Without parameters it will ask the user which relation to load, otherwise it will load filename, giving it name. It shouldn't be called giving filename but not giving name.''' # Asking for file to load if filename == None: filename = QtGui.QFileDialog.getOpenFileName(self, QtGui.QApplication.translate( "Form", "Load Relation"), "", QtGui.QApplication.translate("Form", "Relations (*.csv);;Text Files (*.txt);;All Files (*)")) filename = compatibility.get_filename(filename) # Default relation's name f = filename.split('/') # Split the full path defname = f[len(f) - 1].lower() # Takes only the lowercase filename if len(defname) == 0: return if (defname.endswith(".csv")): # removes the extension defname = defname[:-4] if name == None: # Prompt dialog to insert name for the relation res = QtGui.QInputDialog.getText( self, QtGui.QApplication.translate("Form", "New relation"), QtGui.QApplication.translate( "Form", "Insert the name for the new relation"), QtGui.QLineEdit.Normal, defname) if res[1] == False or len(res[0]) == 0: return # Patch provided by Angelo 'Havoc' Puglisi name = compatibility.get_py_str(res[0]) if not rtypes.is_valid_relation_name(name): r = QtGui.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Error"), r) return try: self.relations[name] = relation.relation(filename) except Exception, e: print e QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__str__())) return
def suggest_name(self, filename): ''' Returns a possible name for a relation, given a filename. If it is impossible to extract a possible name, returns None ''' name = os.path.basename(filename).lower() if len(name) == 0: return None if (name.endswith(".csv")): # removes the extension name = name[:-4] if not is_valid_relation_name(name): return None return name
def promptRelationName(self): while True: res = QtWidgets.QInputDialog.getText( self, QtWidgets.QApplication.translate("Form", "New relation"), QtWidgets.QApplication.translate( "Form", "Insert the name for the new relation"), QtWidgets.QLineEdit.Normal, '') if res[1] == False: # or len(res[0]) == 0: return None name = res[0] if not rtypes.is_valid_relation_name(name): r = QtWidgets.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtWidgets.QMessageBox.information( self, QtWidgets.QApplication.translate("Form", "Error"), r) continue return name
def suggest_name(self, filename: str) -> Optional[str]: ''' Returns a possible name for a relation, given a filename. If it is impossible to extract a possible name, returns None ''' name = os.path.basename(filename).lower() if len(name) == 0: return None if (name.endswith(".csv")): # removes the extension name = name[:-4] if not is_valid_relation_name(name): return None return name
def execute(self): '''Executes the query''' if self.multiline: return self._run_multiline() #Single line query query = self.ui.txtQuery.text() res_rel = self.ui.txtResult.text() # result relation's name if not rtypes.is_valid_relation_name(res_rel): QtWidgets.QMessageBox.information(self, QtWidgets.QApplication.translate( "Form", "Error"), QtWidgets.QApplication.translate("Form", "Wrong name for destination relation.")) return try: # Converting string to utf8 and then from qstring to normal string expr = parser.parse(query) # Converting expression to python code print (query, "-->", expr) # Printing debug result = eval(expr, self.relations) # Evaluating the expression self.relations[ res_rel] = result # Add the relation to the dictionary self.updateRelations() # update the list self.selectedRelation = result self.showRelation(self.selectedRelation) # Show the result in the table except Exception as e: print (str(e)) QtWidgets.QMessageBox.information(None, QtWidgets.QApplication.translate("Form", "Error"), u"%s\n%s" % (QtWidgets.QApplication.translate("Form", "Check your query!"), str(e))) return # Adds to history item = u'%s = %s' % ( self.ui.txtResult.text(), self.ui.txtQuery.text() ) hitem = QtWidgets.QListWidgetItem(None, 0) hitem.setText(item) self.ui.lstHistory.addItem(hitem) self.ui.lstHistory.setCurrentItem(hitem) self.qcounter += 1 self.ui.txtResult.setText(u"_last%d" % self.qcounter) # Sets the result relation name to none
def exec_query(command): '''This function executes a query and prints the result on the screen if the command terminates with ";" the result will not be printed ''' command = unicode(command, 'utf-8') # If it terminates with ; doesn't print the result if command.endswith(';'): command = command[:-1] printrel = False else: printrel = True # Performs replacements for weird operators command = replacements(command) # Finds the name in where to save the query parts = command.split('=', 1) if len(parts) > 1 and rtypes.is_valid_relation_name(parts[0]): relname = parts[0] query = parts[1] else: relname = 'last_' query = command # Execute query try: pyquery = parser.parse(query) result = eval(pyquery, relations) print colorize("-> query: %s" % pyquery.encode('utf-8'), 0x00ff00) if printrel: print print result relations[relname] = result completer.add_completion(relname) except Exception, e: print colorize(str(e), ERROR_COLOR)
def load_relation(filename, defname=None): if not os.path.isfile(filename): return colored("%s is not a file" % filename, 'red') f = filename.split('/') if defname == None: defname = f[len(f) - 1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] if not rtypes.is_valid_relation_name(defname): return colored("%s is not a valid relation name" % defname, 'red') try: relations[defname] = relation.relation(filename) completer.add_completion(defname) out = colored("Loaded relation %s" % defname, 'green', attrs=['bold']) return out + " " + defname except Exception, e: return colored(e, 'red')
def suggest_name(self, filename: str) -> Optional[str]: ''' Returns a possible name for a relation, given a filename. If it is impossible to extract a possible name, returns None ''' name = os.path.basename(filename).lower() if len(name) == 0: return None # Removing the extension try: pos = name.rindex('.') except ValueError: return None name = name[:pos] if not is_valid_relation_name(name): return None return name
def __init__(self, expression=None): '''Generates the tree from the tokenized expression If no expression is specified then it will create an empty node''' if expression == None or len(expression) == 0: return # If the list contains only a list, it will consider the lower level list. # This will allow things like ((((((a))))) to work while len(expression) == 1 and isinstance(expression[0], list): expression = expression[0] # The list contains only 1 string. Means it is the name of a relation if len(expression) == 1: self.kind = RELATION self.name = expression[0] if not rtypes.is_valid_relation_name(self.name): raise ParserException( u"'%s' is not a valid relation name" % self.name) return '''Expression from right to left, searching for binary operators this means that binary operators have lesser priority than unary operators. It finds the operator with lesser priority, uses it as root of this (sub)tree using everything on its left as left parameter (so building a left subtree with the part of the list located on left) and doing the same on right. Since it searches for strings, and expressions into parenthesis are within sub-lists, they won't be found here, ensuring that they will have highest priority.''' for i in range(len(expression) - 1, -1, -1): if expression[i] in b_operators: # Binary operator self.kind = BINARY self.name = expression[i] if len(expression[:i]) == 0: raise ParserException( u"Expected left operand for '%s'" % self.name) if len(expression[i + 1:]) == 0: raise ParserException( u"Expected right operand for '%s'" % self.name) self.left = node(expression[:i]) self.right = node(expression[i + 1:]) return '''Searches for unary operators, parsing from right to left''' for i in range(len(expression) - 1, -1, -1): if expression[i] in u_operators: # Unary operator self.kind = UNARY self.name = expression[i] if len(expression) <= i + 2: raise ParserException( u"Expected more tokens in '%s'" % self.name) self.prop = expression[1 + i].strip() self.child = node(expression[2 + i]) return raise ParserException(u"Unable to parse tokens") pass
def __init__(self, expression: Optional[list] = None) -> None: '''Generates the tree from the tokenized expression If no expression is specified then it will create an empty node''' if expression == None or len(expression) == 0: return # If the list contains only a list, it will consider the lower level list. # This will allow things like ((((((a))))) to work while len(expression) == 1 and isinstance(expression[0], list): expression = expression[0] # The list contains only 1 string. Means it is the name of a relation if len(expression) == 1: self.kind = RELATION self.name = expression[0] if not rtypes.is_valid_relation_name(self.name): raise ParserException(u"'%s' is not a valid relation name" % self.name) return # Expression from right to left, searching for binary operators # this means that binary operators have lesser priority than # unary operators. # It finds the operator with lesser priority, uses it as root of this # (sub)tree using everything on its left as left parameter (so building # a left subtree with the part of the list located on left) and doing # the same on right. # Since it searches for strings, and expressions into parenthesis are # within sub-lists, they won't be found here, ensuring that they will # have highest priority. for i in range(len(expression) - 1, -1, -1): if expression[i] in b_operators: # Binary operator self.kind = BINARY self.name = expression[i] if len(expression[:i]) == 0: raise ParserException(u"Expected left operand for '%s'" % self.name) if len(expression[i + 1:]) == 0: raise ParserException(u"Expected right operand for '%s'" % self.name) self.left = node(expression[:i]) self.right = node(expression[i + 1:]) return '''Searches for unary operators, parsing from right to left''' for i in range(len(expression) - 1, -1, -1): if expression[i] in u_operators: # Unary operator self.kind = UNARY self.name = expression[i] if len(expression) <= i + 2: raise ParserException(u"Expected more tokens in '%s'" % self.name) self.prop = expression[1 + i].strip() self.child = node(expression[2 + i]) return raise ParserException("Expected operator in '%s'" % expression)
def set_relation(self, name, rel): '''Sets the relation corresponding to name.''' if not is_valid_relation_name(name): raise Exception('Invalid name for destination relation') self.relations[name] = rel
def set_relation(self, name: str, rel: Relation) -> None: '''Sets the relation corresponding to name.''' if not is_valid_relation_name(name): raise Exception(_('Invalid name for destination relation')) self.relations[name] = rel