fix(py): Fixed Scrap conditions system.
This commit is contained in:
parent
dc026f162e
commit
f1807f5f9d
@ -10,6 +10,7 @@ from AnP.DSLs.ScrapDSL import (
|
|||||||
If, While, DoWhile, Download, Selector, Condition
|
If, While, DoWhile, Download, Selector, Condition
|
||||||
)
|
)
|
||||||
from AnP.Utils.Common import Common
|
from AnP.Utils.Common import Common
|
||||||
|
from AnP.Utils.Checks import Check
|
||||||
from AnP.Abstracts.ModelAbstract import ModelAbstract
|
from AnP.Abstracts.ModelAbstract import ModelAbstract
|
||||||
from AnP.Models.BrowserTabsModel import BrowserBoxModel
|
from AnP.Models.BrowserTabsModel import BrowserBoxModel
|
||||||
|
|
||||||
@ -251,12 +252,15 @@ class BrowserAbstract(ModelAbstract):
|
|||||||
elif isinstance(action, bool):
|
elif isinstance(action, bool):
|
||||||
return action
|
return action
|
||||||
elif isinstance(action, Selector):
|
elif isinstance(action, Selector):
|
||||||
return self.get_selector(action, box)
|
return not not self.get_selector(action, box)
|
||||||
elif callable(action):
|
elif callable(action):
|
||||||
try:
|
try:
|
||||||
return action(shared)
|
return action(shared)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
action.exception = exception
|
self.anp.exception(exception, "anp_browser_condition_exception", {
|
||||||
|
"key" : self.key
|
||||||
|
})
|
||||||
|
# action.exception = exception
|
||||||
else:
|
else:
|
||||||
action.print_errors and self.anp.print("warning", "anp_browser_condition_not_supported", {
|
action.print_errors and self.anp.print("warning", "anp_browser_condition_not_supported", {
|
||||||
"key" : self.key
|
"key" : self.key
|
||||||
@ -290,23 +294,29 @@ class BrowserAbstract(ModelAbstract):
|
|||||||
|
|
||||||
def _if(self:Self, action:If, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
def _if(self:Self, action:If, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
||||||
|
|
||||||
if not isinstance(action.condition, Condition):
|
# if not isinstance(action.condition, Condition):
|
||||||
action.condition = Condition((action.condition,))
|
# action.condition = Condition((action.condition,))
|
||||||
|
|
||||||
self.do(action.condition, shared, box)
|
# self.do(action.condition, shared, box)
|
||||||
|
|
||||||
if action.condition.done and action.condition.exception is None:
|
# if action.condition.done and action.condition.exception is None:
|
||||||
|
|
||||||
subactions:Do = Do(*((action.if_actions if action.condition.ok else action.else_actions) or []))
|
# subactions:Do = Do(*((action.if_actions if action.condition.ok else action.else_actions) or []))
|
||||||
|
|
||||||
|
# self.do(subactions, shared, box)
|
||||||
|
# action.done = subactions.done and subactions.exception is None
|
||||||
|
# action.exception = subactions.exception
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# action.done = action.condition.done
|
||||||
|
# action.exception = action.condition.exception
|
||||||
|
|
||||||
|
subactions:Do = Do(*((action.if_actions if self.__condition(action.condition, shared, box) else action.else_actions) or []))
|
||||||
|
|
||||||
self.do(subactions, shared, box)
|
self.do(subactions, shared, box)
|
||||||
action.done = subactions.done and subactions.exception is None
|
action.done = subactions.done and subactions.exception is None
|
||||||
action.exception = subactions.exception
|
action.exception = subactions.exception
|
||||||
|
|
||||||
else:
|
|
||||||
action.done = action.condition.done
|
|
||||||
action.exception = action.condition.exception
|
|
||||||
|
|
||||||
def _while(self:Self, action:While, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
def _while(self:Self, action:While, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
||||||
|
|
||||||
if not isinstance(action.condition, Condition):
|
if not isinstance(action.condition, Condition):
|
||||||
@ -319,13 +329,13 @@ class BrowserAbstract(ModelAbstract):
|
|||||||
|
|
||||||
self.do(action.condition, shared, box)
|
self.do(action.condition, shared, box)
|
||||||
|
|
||||||
if not action.condition.done or action.condition.exception is not None:
|
# if not action.condition.done or action.condition.exception is not None:
|
||||||
action.done = action.condition.done
|
if not self.__condition(action.condition, shared, box):
|
||||||
action.exception = action.condition.exception
|
action.done = True
|
||||||
|
# action.done = action.condition.done
|
||||||
|
# action.exception = action.condition.exception
|
||||||
break
|
break
|
||||||
|
|
||||||
if action.condition.ok:
|
|
||||||
|
|
||||||
subactions:Do = Do(*action.actions)
|
subactions:Do = Do(*action.actions)
|
||||||
|
|
||||||
self.do(subactions, shared, box)
|
self.do(subactions, shared, box)
|
||||||
@ -334,14 +344,24 @@ class BrowserAbstract(ModelAbstract):
|
|||||||
action.done = False
|
action.done = False
|
||||||
break
|
break
|
||||||
|
|
||||||
else:
|
# if action.condition.ok:
|
||||||
action.done = True
|
|
||||||
break
|
# subactions:Do = Do(*action.actions)
|
||||||
|
|
||||||
|
# self.do(subactions, shared, box)
|
||||||
|
# if not subactions.done or subactions.exception is not None:
|
||||||
|
# action.exception = subactions.exception
|
||||||
|
# action.done = False
|
||||||
|
# break
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# action.done = True
|
||||||
|
# break
|
||||||
|
|
||||||
def do_while(self:Self, action:DoWhile, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
def do_while(self:Self, action:DoWhile, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
||||||
|
|
||||||
if not isinstance(action.condition, Condition):
|
# if not isinstance(action.condition, Condition):
|
||||||
action.condition = Condition((action.condition,))
|
# action.condition = Condition((action.condition,))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if not self.is_working(box):
|
if not self.is_working(box):
|
||||||
@ -359,12 +379,16 @@ class BrowserAbstract(ModelAbstract):
|
|||||||
subactions = Do(*action.actions)
|
subactions = Do(*action.actions)
|
||||||
self.do(subactions, shared, box)
|
self.do(subactions, shared, box)
|
||||||
|
|
||||||
if not action.condition.done or action.condition.exception is not None:
|
# if not action.condition.done or action.condition.exception is not None:
|
||||||
action.done = action.condition.done
|
# action.done = action.condition.done
|
||||||
action.exception = action.condition.exception
|
# action.exception = action.condition.exception
|
||||||
break
|
# break
|
||||||
|
|
||||||
if not action.condition.ok:
|
# if not action.condition.ok:
|
||||||
|
# action.done = True
|
||||||
|
# break
|
||||||
|
|
||||||
|
if not self.__condition(action.condition, shared, box):
|
||||||
action.done = True
|
action.done = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,11 @@ class Action:
|
|||||||
class Execute(Action):
|
class Execute(Action):
|
||||||
def __init__(self:Self, callback:Callable[[dict[str, Any|None]], None]) -> None:
|
def __init__(self:Self, callback:Callable[[dict[str, Any|None]], None]) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.callback:Callable[[dict[str, Any|None]], None] = callback
|
self.callback:Callable[[dict[str, Any|None]], None] = callback
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class Open(Action):
|
class Open(Action):
|
||||||
def __init__(self:Self, key:str, url:Optional[str] = None) -> None:
|
def __init__(self:Self, key:str, url:Optional[str] = None) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -93,6 +96,8 @@ class Get(Action):
|
|||||||
self.pattern:REPattern|None = None
|
self.pattern:REPattern|None = None
|
||||||
self.matches:str|Callable[[REMatch], str]|None = None
|
self.matches:str|Callable[[REMatch], str]|None = None
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
if pattern is not None:
|
if pattern is not None:
|
||||||
self.pattern, self.matches = pattern
|
self.pattern, self.matches = pattern
|
||||||
|
|
||||||
@ -103,16 +108,22 @@ class ForEach(Action):
|
|||||||
callback:Optional[Callable[[Any|None], None]] = None
|
callback:Optional[Callable[[Any|None], None]] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.items:Selector|Sequence[Any|None] = items
|
self.items:Selector|Sequence[Any|None] = items
|
||||||
self.actions:Sequence[Action] = actions
|
self.actions:Sequence[Action] = actions
|
||||||
self.callback:Callable[[Any|None], None]|None = callback
|
self.callback:Callable[[Any|None], None]|None = callback
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class Condition(Action):
|
class Condition(Action):
|
||||||
def __init__(self:Self, conditions:Sequence[Callable[[dict[str, Any|None]], bool]]|Selector|Self) -> None:
|
def __init__(self:Self, conditions:Sequence[Callable[[dict[str, Any|None]], bool]]|Selector|Self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.conditions:Sequence[Callable[[dict[str, Any|None]], bool]|Selector|Condition|bool] = conditions
|
self.conditions:Sequence[Callable[[dict[str, Any|None]], bool]|Selector|Condition|bool] = conditions
|
||||||
self.ok:bool = False
|
self.ok:bool = False
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class And(Condition):pass
|
class And(Condition):pass
|
||||||
|
|
||||||
class Or(Condition):pass
|
class Or(Condition):pass
|
||||||
@ -130,28 +141,37 @@ class If(Action):
|
|||||||
else_actions:Optional[Sequence[Action]] = None
|
else_actions:Optional[Sequence[Action]] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
||||||
self.if_actions:Sequence[Action]|None = if_actions
|
self.if_actions:Sequence[Action]|None = if_actions
|
||||||
self.else_actions:Sequence[Action]|None = else_actions
|
self.else_actions:Sequence[Action]|None = else_actions
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class While(Action):
|
class While(Action):
|
||||||
def __init__(self:Self,
|
def __init__(self:Self,
|
||||||
condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool,
|
condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool,
|
||||||
actions:Sequence[Action]
|
actions:Sequence[Action]
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
||||||
self.actions:Sequence[Action] = actions
|
self.actions:Sequence[Action] = actions
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class DoWhile(Action):
|
class DoWhile(Action):
|
||||||
def __init__(self:Self,
|
def __init__(self:Self,
|
||||||
condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool,
|
condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool,
|
||||||
actions:Sequence[Action]
|
actions:Sequence[Action]
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
self.condition:Condition|Callable[[dict[str, Any|None]], bool]|Selector|bool = condition
|
||||||
self.actions:Sequence[Action] = actions
|
self.actions:Sequence[Action] = actions
|
||||||
|
|
||||||
|
self.wait = False
|
||||||
|
|
||||||
class Download(Action):
|
class Download(Action):
|
||||||
def __init__(self:Self,
|
def __init__(self:Self,
|
||||||
url:str,
|
url:str,
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class SQLiteDriver(DatabaseAbstract):
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
"null" if value is None else
|
"null" if value is None else
|
||||||
"'" + value + "'" if Check.is_string(value) else
|
"'" + value.replace("'", "''") + "'" if Check.is_string(value) else
|
||||||
("1" if value is True else "0") if Check.is_boolean(value) else
|
("1" if value is True else "0") if Check.is_boolean(value) else
|
||||||
# "'" + value.strftime("%Y-%m-%d %H:%M:%S") + "'" if Check.is_date(value) else
|
# "'" + value.strftime("%Y-%m-%d %H:%M:%S") + "'" if Check.is_date(value) else
|
||||||
"'" + value.isoformat(sep = " ") + "'" if Check.is_date(value) else
|
"'" + value.isoformat(sep = " ") + "'" if Check.is_date(value) else
|
||||||
@ -83,6 +83,8 @@ class SQLiteDriver(DatabaseAbstract):
|
|||||||
position:int|None
|
position:int|None
|
||||||
subquery:str = ""
|
subquery:str = ""
|
||||||
|
|
||||||
|
query = RE.SQLITE_COMMENTS.sub(r'', query)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
lower:str|None = None
|
lower:str|None = None
|
||||||
@ -142,25 +144,39 @@ class SQLiteDriver(DatabaseAbstract):
|
|||||||
|
|
||||||
for i, sentence in enumerate(sentences):
|
for i, sentence in enumerate(sentences):
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
row:list[Any]
|
row:list[Any]
|
||||||
columns:list[str]
|
columns:list[str]
|
||||||
|
table:list[Any|None]
|
||||||
|
|
||||||
cursor.execute(sentence)
|
cursor.execute(sentence)
|
||||||
columns = [
|
columns = [
|
||||||
column[0] for column in cursor.description
|
column[0] for column in cursor.description
|
||||||
] if cursor.description is not None else []
|
] if cursor.description is not None else []
|
||||||
self.__connection.commit()
|
self.__connection.commit()
|
||||||
|
table = cursor.fetchall()
|
||||||
|
|
||||||
for row in cursor.fetchall():
|
if len(table):
|
||||||
|
for row in table:
|
||||||
response.add(i, dict(zip(columns, row)))
|
response.add(i, dict(zip(columns, row)))
|
||||||
|
else:
|
||||||
|
response.tables.append([])
|
||||||
|
|
||||||
|
except Exception as exception:
|
||||||
|
self.anp.exception(exception, "anp_sqlite_driver_execution_sentence_exception", {
|
||||||
|
"path" : self.__path,
|
||||||
|
"i" : i,
|
||||||
|
"sentence" : sentence
|
||||||
|
})
|
||||||
|
print(sentence)
|
||||||
|
break
|
||||||
|
|
||||||
self.__connection.commit()
|
self.__connection.commit()
|
||||||
|
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
self.anp.exception(exception, "anp_sqlite_driver_execution_exception", {
|
self.anp.exception(exception, "anp_sqlite_driver_execution_exception", {
|
||||||
"path" : self.__path,
|
"path" : self.__path
|
||||||
"i" : i,
|
|
||||||
"sentence" : sentence
|
|
||||||
})
|
})
|
||||||
self.__connection.rollback()
|
self.__connection.rollback()
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ class XMLScrapDriver(BrowserAbstract):
|
|||||||
self.__load(action, action.key, action.url, shared, box)
|
self.__load(action, action.key, action.url, shared, box)
|
||||||
|
|
||||||
def go(self:Self, action:Go, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
def go(self:Self, action:Go, shared:dict[str, Any|None], box:BrowserBoxModel) -> None:
|
||||||
self.__load(action, action.key, action.url, shared, box)
|
self.__load(action, None, action.url, shared, box)
|
||||||
|
|
||||||
def get_selector(self:Self, selector:Selector, box:BrowserBoxModel, force_multiple:bool = False) -> Any|list[Any]|None:
|
def get_selector(self:Self, selector:Selector, box:BrowserBoxModel, force_multiple:bool = False) -> Any|list[Any]|None:
|
||||||
|
|
||||||
|
|||||||
@ -62,11 +62,10 @@ class ControllersManager:
|
|||||||
controller if Check.is_dictionary(controller) else
|
controller if Check.is_dictionary(controller) else
|
||||||
None))
|
None))
|
||||||
|
|
||||||
def execute(self:Self, key:str, method:str, request:RequestModel) -> bool:
|
def execute(self:Self, key:str, method:str, request:RequestModel) -> Any|None:
|
||||||
if key in self.__controllers and hasattr(self.__controllers[key], method):
|
if key in self.__controllers and hasattr(self.__controllers[key], method):
|
||||||
getattr(self.__controllers[key], method)(request)
|
return getattr(self.__controllers[key], method)(request)
|
||||||
return True
|
return None
|
||||||
return False
|
|
||||||
|
|
||||||
def get(self:Self, key:str, Type:type[ControllerType]) -> ControllerType|None:
|
def get(self:Self, key:str, Type:type[ControllerType]) -> ControllerType|None:
|
||||||
if key in self.__controllers and isinstance(self.__controllers[key], Type):
|
if key in self.__controllers and isinstance(self.__controllers[key], Type):
|
||||||
|
|||||||
@ -35,17 +35,17 @@ class DispatchesManager:
|
|||||||
|
|
||||||
for subinputs in self.anp.files.load_json(inputs, True):
|
for subinputs in self.anp.files.load_json(inputs, True):
|
||||||
|
|
||||||
key:str
|
via:str
|
||||||
subinputs:dict[str, Any|None]
|
subinputs:dict[str, Any|None]
|
||||||
|
|
||||||
for key, subinputs in subinputs.items():
|
for via, subinputs in subinputs.items():
|
||||||
if Check.is_mark_key(key) and dispatch is None:
|
if Check.is_mark_key(via) and dispatch is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
via:str
|
key:str
|
||||||
dispatch:Any|None
|
dispatch:Any|None
|
||||||
|
|
||||||
for via, dispatch in subinputs.items():
|
for key, dispatch in subinputs.items():
|
||||||
|
|
||||||
DispatchClass:type[DispatchAbstract]|None
|
DispatchClass:type[DispatchAbstract]|None
|
||||||
|
|
||||||
|
|||||||
@ -81,3 +81,6 @@ class HashModel():
|
|||||||
|
|
||||||
def compare(self:Self, other:Self) -> bool:
|
def compare(self:Self, other:Self) -> bool:
|
||||||
return all(getattr(self, name) == getattr(other, name) for name in self.__hashes)
|
return all(getattr(self, name) == getattr(other, name) for name in self.__hashes)
|
||||||
|
|
||||||
|
def get_dictionary(self:Self) -> dict[str, str]:
|
||||||
|
return {name : getattr(self, name) for name in self.__hashes}
|
||||||
@ -21,6 +21,7 @@ class RE:
|
|||||||
HTTP_REQUEST:REPattern = re_compile(r'^([^\s]+)\s([^\s\?\#]+)(?:\?([^#]+))?(?:\#([^\s]+))?\s([^\/]+)\/([0-9\.]+)$')
|
HTTP_REQUEST:REPattern = re_compile(r'^([^\s]+)\s([^\s\?\#]+)(?:\?([^#]+))?(?:\#([^\s]+))?\s([^\/]+)\/([0-9\.]+)$')
|
||||||
PYTHON_MODULES_PATH:REPattern = re_compile(r'[\/\\]python[0-9\.]+[\/\\]site-packages[\/\\]?$', RE_IGNORECASE)
|
PYTHON_MODULES_PATH:REPattern = re_compile(r'[\/\\]python[0-9\.]+[\/\\]site-packages[\/\\]?$', RE_IGNORECASE)
|
||||||
ODBC_STRING_VARIABLE:REPattern = re_compile(r'\{([a-z_][a-z0-9_]*)\}|@([a-z0-9_]+)', RE_IGNORECASE)
|
ODBC_STRING_VARIABLE:REPattern = re_compile(r'\{([a-z_][a-z0-9_]*)\}|@([a-z0-9_]+)', RE_IGNORECASE)
|
||||||
|
SQLITE_COMMENTS:REPattern = re_compile(r'--[^\r\n]*|\/\*(?:[^\*]|\*+[^\/\*]|[\r\n]+)*\*+\/')
|
||||||
|
|
||||||
# ORM
|
# ORM
|
||||||
ORM_MAIN_BLOCKS:REPattern = re_compile(r'((?:(?!(?:(?:\r\n){2}|[\r\n]{2}))(?:.|[\r\n]))+)(?:(?:\r\n){2}|[\r\n]{2})((?:.+|[\r\n]+)+)')
|
ORM_MAIN_BLOCKS:REPattern = re_compile(r'((?:(?!(?:(?:\r\n){2}|[\r\n]{2}))(?:.|[\r\n]))+)(?:(?:\r\n){2}|[\r\n]{2})((?:.+|[\r\n]+)+)')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user