Skip to content

Commit

Permalink
Add task scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
inquilabee committed Nov 24, 2024
1 parent bf17364 commit 4476849
Show file tree
Hide file tree
Showing 14 changed files with 459 additions and 251 deletions.
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repos:
- id: detect-private-key

- repo: https://github.com/asottile/pyupgrade
rev: v3.17.0
rev: v3.19.0
hooks:
- id: pyupgrade
args: [ --py311-plus ]
Expand All @@ -30,19 +30,19 @@ repos:

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.4
rev: v0.8.0
hooks:
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
types_or: [ python, pyi, jupyter ]

- repo: https://github.com/psf/black
rev: 24.8.0
rev: 24.10.0
hooks:
- id: black

- repo: https://github.com/PyCQA/bandit
rev: 1.7.9
rev: 1.7.10
hooks:
- id: bandit
args: [ "-c", "bandit.yaml" ]
Expand Down
9 changes: 9 additions & 0 deletions .trunk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*out
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
tmp
2 changes: 2 additions & 0 deletions .trunk/configs/.markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Prettier friendly markdownlint config (all formatting rules disabled)
extends: markdownlint/style/prettier
7 changes: 7 additions & 0 deletions .trunk/configs/.shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154

# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091
7 changes: 7 additions & 0 deletions .trunk/configs/.yamllint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
key-duplicates: {}
octal-values:
forbid-implicit-octal: true
44 changes: 44 additions & 0 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# This file controls the behavior of Trunk: https://docs.trunk.io/cli
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.22.5
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
plugins:
sources:
- id: trunk
ref: v1.6.5
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- [email protected]
- [email protected]
- [email protected]
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
enabled:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- git-diff-check
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
actions:
disabled:
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled:
- trunk-upgrade-available
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
415 changes: 213 additions & 202 deletions poetry.lock

Large diffs are not rendered by default.

122 changes: 82 additions & 40 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.black]
line-length = 120
target-version = ['py311']
target-version = ['py312']
include = '\.pyi?$'
exclude = '''
/(
Expand All @@ -13,48 +13,48 @@ exclude = '''
|Jenkinfile
| _build
| dist
| .venv
)/
'''

# ==== isort ====
[tool.isort]
profile = "black"
line_length = 120
known_first_party = [
"config",
"apps",
]
known_first_party = ["config", "apps"]
skip = []
skip_glob = []

[tool.poetry]
name = "seleniumtabs"
version = "0.5.7"
packages = [
{ include = "seleniumtabs" },
]
version = "1.0.0"
packages = [{ include = "seleniumtabs" }]
description = "Selenium with tab management in Python"
authors = ["Vishal Kumar Mishra <[email protected]>"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/TheConfused/selenium-tabs"
repository = "https://github.com/TheConfused/selenium-tabs"
keywords = ["selenium tabs", "selenium python", "selenium python automation", "python automation", ]
include = [
"LICENSE",
keywords = [
"selenium tabs",
"selenium python",
"selenium python automation",
"python automation",
]
include = ["LICENSE"]

[tool.poetry.dependencies]
python = "^3.10"
python = "^3.13"
selenium = "^4.12.0"
django-environ = "^0.11.1"
python-dotenv = "^1.0.0"
PyYAML = "^6.0.1"
pyquery = "^2.0.0"
browserjquery = "^0.1.0"
fake-useragent = "^1.2.1"
tldextract = "^3.6.0"
tldextract = "^5.1.2"
webdriver-manager = "^4.0.2"
schedule = "^1.2.2"


[tool.poetry.dev-dependencies]
Expand All @@ -75,10 +75,7 @@ build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--ds=settings"
python_files = [
"tests.py",
"test_*.py",
]
python_files = ["tests.py", "test_*.py"]

# ==== mypy ====
[tool.mypy]
Expand All @@ -96,32 +93,77 @@ select = ["E", "F"]
ignore = []

# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
fixable = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"I",
"N",
"Q",
"S",
"T",
"W",
"ANN",
"ARG",
"BLE",
"COM",
"DJ",
"DTZ",
"EM",
"ERA",
"EXE",
"FBT",
"ICN",
"INP",
"ISC",
"NPY",
"PD",
"PGH",
"PIE",
"PL",
"PT",
"PTH",
"PYI",
"RET",
"RSE",
"RUF",
"SIM",
"SLF",
"TCH",
"TID",
"TRY",
"UP",
"YTT",
]
unfixable = []

# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
]

line-length = 120
Expand Down
4 changes: 4 additions & 0 deletions seleniumtabs/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from seleniumtabs.browser_management import browser_sessions
from seleniumtabs.exceptions import SeleniumRequestException
from seleniumtabs.schedule_tasks import task_scheduler
from seleniumtabs.session import Session
from seleniumtabs.tabs import Tab, TabManager
from seleniumtabs.wait import humanized_wait
Expand Down Expand Up @@ -113,6 +114,9 @@ def _remove_tab(self, tab: Tab):

self._tabs and self._tabs.last_tab.switch()

def execute_task(self, max_time=None):
task_scheduler.execute_tasks(max_time)


if __name__ == "__main__":
err_msg = "Something went wrong. Report!"
Expand Down
15 changes: 10 additions & 5 deletions seleniumtabs/browser_management.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
class BrowserSessions:
def __init__(self):
self.sessions = []
self.browser_sessions = []

def get_browser_for_tab(self, tab):
if browser := [browser for browser in self.browser_sessions if tab in browser]:
return browser[0]

return None

def close_tab(self, tab):
if browser := [browser for browser in self.sessions if tab in browser]:
br = browser[0]
br.close_tab(tab)
if browser := self.get_browser_for_tab(tab):
browser.close_tab(tab)

def add_browser(self, br):
self.sessions.append(br)
self.browser_sessions.append(br)


browser_sessions = BrowserSessions()
49 changes: 49 additions & 0 deletions seleniumtabs/schedule_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import time

import schedule

from seleniumtabs import settings

logger = settings.getLogger(__name__)


class BrowserTaskScheduler:
"""
A class to manage and schedule tasks across multiple tabs in a Selenium browser.
"""

def schedule_task(self, tab, task_func, period, *args, **kwargs):
"""
Schedule a task to be executed on a specific tab.
:param tab: The tab object to execute the task on.
:param task_func: The function to execute as a task.
:param args: Arguments for the task function.
:param kwargs: Keyword arguments for the task function.
"""

def task_decorator(task):
def wrapper(tab, *args, **kwargs):
tab.switch()
time.sleep(0.25)
task(tab, *args, **kwargs)

return wrapper

schedule.every(period).seconds.do(task_decorator(task_func), tab, *args, **kwargs)

def execute_tasks(self, max_time=None):
"""
Execute all scheduled tasks across their respective tabs.
"""
start_time = time.time()

while True:
schedule.run_pending()
time.sleep(1)

if max_time and time.time() - start_time > max_time:
break


task_scheduler = BrowserTaskScheduler()
Loading

0 comments on commit 4476849

Please sign in to comment.