Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ load-plugins=
# Pickle collected data for later comparisons.
persistent=yes

# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: "3.13"


# Build documentation in the docs/ directory with Sphinx
Expand Down
5 changes: 3 additions & 2 deletions common/testUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.webdriver import WebDriver as Chrome
from scraper.models import MultiScraper, Scraper
from visualizer.models import JsonConfig
from visualizer.tests import filenames
Expand Down Expand Up @@ -76,9 +77,9 @@ def get_headless_browser(cls):
if 'CHROMEDRIVER_PATH' in os.environ:
chromeOptions.add_argument("--remote-debugging-port=9222")
service = ChromeService(executable_path=os.environ["CHROMEDRIVER_PATH"])
return webdriver.Chrome(service=service, options=chromeOptions)
return Chrome(service=service, options=chromeOptions)

return webdriver.Chrome(options=chromeOptions)
return Chrome(options=chromeOptions)

# Or, Firefox
# firefoxOptions = webdriver.FirefoxOptions()
Expand Down
8 changes: 8 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@

sys.path.insert(0, os.path.abspath('../../'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'rcvis.settings'

# Sphinx 9's autodoc calls repr() on class attributes such as the REST views'
# `queryset = Model.objects.all()`, which queries the database. Read the Docs has
# no database, so give the docs build an empty in-memory one with every table.
from django.conf import settings # noqa: E402 pylint: disable=wrong-import-position
settings.DATABASES['default']['NAME'] = ':memory:'
django.setup()
from django.core.management import call_command # noqa: E402 pylint: disable=wrong-import-position
call_command('migrate', verbosity=0)

# -- Project information -----------------------------------------------------

Expand Down
36 changes: 18 additions & 18 deletions infra/requirements-core.txt
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
boto3==1.38.38
boto3==1.43.90
csscompressor==0.9.5
django-admin-cursor-paginator==0.1.6
django-compressor==4.5.1
django-admin-cursor-paginator==0.1.7
django-compressor==4.6.0
django-extra-views==0.16.0
django-node-assets==0.9.15
django-node-assets==0.9.16
django-registration==5.2.1
django-social-share==2.3.0
django-sortedm2m==4.0.0
django-storages==1.14.6
Django==5.2.16
Django==6.1.1
rcvformats==0.0.46
selenium==4.31.0 # Stay below 4.32.0 until this is fixed: https://github.com/SeleniumHQ/selenium/issues/15772
requests==2.33.0
whitenoise==6.4.0
selenium==4.48.0
requests==2.34.2
whitenoise==6.12.0

# For tests
mock==5.2.0
requests-mock==1.12.0
requests-mock==1.12.1
django_extensions==4.1

# For coverage
autopep8==2.3.2
coverage==7.9.1
pylint==3.3.7
pylint-django==2.6.1
pycodestyle==2.13.0
coverage==7.16.0
pylint==4.0.8
pylint-django==2.8.0
pycodestyle==2.14.0

# For django-rest
djangorestframework==3.17.2
djangorestframework==3.18.1
drf-api-tracking==1.8.4
markdown==3.8.1
markdown==3.10.3

# For movie creation
celery==5.5.3
celery==5.6.3
django-cleanup==9.0.0
moviepy==2.2.1
pillow<12.0.0 # Highest version supported by moviepy
pillow<13.0.0 # Highest version supported by moviepy

# For Heroku
gunicorn==23.0.0
gunicorn==26.2.0
django-on-heroku==1.1.2
8 changes: 4 additions & 4 deletions infra/requirements-for-readthedocs.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-r requirements-core.txt

# For docs
sphinx<7
sphinx-mdinclude==0.5.3
sphinx-rtd-theme==1.2.2
mistune<3
sphinx<10
sphinx-mdinclude==0.6.2
sphinx-rtd-theme==3.1.0
mistune<4
2 changes: 1 addition & 1 deletion infra/requirements-not-for-readthedocs.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# For movie creation
pycurl==7.45.4
pycurl==7.47.0
5 changes: 3 additions & 2 deletions movie/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.webdriver import WebDriver as Chrome

from movie.creation.movieCreator import MovieCreationFactory
from visualizer.models import JsonConfig, MovieGenerationStatuses
Expand Down Expand Up @@ -59,9 +60,9 @@ def create_movie_task(pk, domain):
if 'CHROMEDRIVER_PATH' in os.environ:
chromeOptions.add_argument("--remote-debugging-port=9222")
service = ChromeService(executable_path=os.environ["CHROMEDRIVER_PATH"])
browser = webdriver.Chrome(service=service, options=chromeOptions)
browser = Chrome(service=service, options=chromeOptions)
else:
browser = webdriver.Chrome(options=chromeOptions)
browser = Chrome(options=chromeOptions)

browser.implicitly_wait(10)

Expand Down
4 changes: 2 additions & 2 deletions rcvis/celeryconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# No backend - we don't care about the results, we'll update the database
result_backend = None # pylint: disable=invalid-name

task_annotations = {
task_annotations = { # pylint: disable=invalid-name
'tasks.create_movie_task': {'rate_limit': '1/s'}
}

Expand All @@ -20,7 +20,7 @@
# Otherwise we get a cryptic error message
raise NotImplementedError("No queue name set. Set SQS_QUEUE_NAME.")

broker_transport_options = {
broker_transport_options = { # pylint: disable=invalid-name
'queue_name_prefix': sqs_queue_name
}

Expand Down
5 changes: 3 additions & 2 deletions visualizer/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def create_headless_browser():
"""Create a browser with internal imports for use in process pool executor"""
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.webdriver import WebDriver as Chrome

chromeOptions = webdriver.ChromeOptions()
for arg in [
Expand All @@ -24,11 +25,11 @@ def create_headless_browser():
chromedriverPath = os.getenv('CHROMEDRIVER_PATH')
if chromedriverPath:
chromeOptions.add_argument("--remote-debugging-port=9222")
return webdriver.Chrome(
return Chrome(
service=ChromeService(
executable_path=chromedriverPath),
options=chromeOptions)
return webdriver.Chrome(options=chromeOptions)
return Chrome(options=chromeOptions)


def generate_json_config_title_image(pk, domain):
Expand Down
2 changes: 1 addition & 1 deletion visualizer/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from unittest.mock import MagicMock, patch

executor_mock = MagicMock()
executor_mock = MagicMock() # pylint: disable=invalid-name

patcher = patch("visualizer.executor.get_executor", MagicMock(return_value=executor_mock))
patcher.start()
8 changes: 6 additions & 2 deletions visualizer/tests/liveServerTestBaseClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.command import Command
from selenium.webdriver.remote.webdriver import WebDriver as Remote
from selenium.webdriver.support.ui import Select

from common.testUtils import TestHelpers
Expand Down Expand Up @@ -59,7 +61,7 @@ def setUp(self):
options.set_capability('sauce:options', sauceOptions)

seleniumEndpoint = f"https://{username}:{accessKey}@ondemand.saucelabs.com:443/wd/hub"
self.browser = webdriver.Remote(command_executor=seleniumEndpoint, options=options)
self.browser = Remote(command_executor=seleniumEndpoint, options=options)
else:
self.browser = TestHelpers.get_headless_browser()
self.browser.set_window_size(1280, 1024)
Expand Down Expand Up @@ -108,7 +110,9 @@ def _has_test_failed(self):

def _get_log(self):
""" Returns and clears the console log """
return self.browser.get_log('browser')
# Selenium 4.32+ removed get_log() from webdriver.Remote (used for SauceLabs),
# but the underlying command is still registered on every driver, so call it directly.
return self.browser.execute(Command.GET_LOG, {'type': 'browser'})['value']

def _assert_log_len(self, num):
""" Asserts the log contains num elements, or prints out what's in the log.
Expand Down
4 changes: 2 additions & 2 deletions visualizer/tests/testSidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _test_ballotpedia_text_with_config(self, uploadConfig, testConfigFuncs):
'incumbentsBolded': b'Incumbents are <span class="dataLabelIncumbent">'
b'bolded and underlined</span>',
'noIncumbents': b'There were no incumbents in this race',
'source': b'<a href="http://test.com">Source [test.com]</a>'
'source': b'<a href="https://test.com">Source [test.com]</a>'
}

# Look through the test config to see if the text should be in or not in the HTML
Expand Down Expand Up @@ -174,7 +174,7 @@ def test_ballotpedia_text(self):
self._test_ballotpedia_text_with_config({
'jsonFile': jsonFile,
'candidateSidecarFile': sidecarFile,
'dataSourceURL': 'test.com', # note: http:// is auto-added
'dataSourceURL': 'test.com', # note: https:// is auto-added
'areResultsCertified': True
}, {
'title': self.assertIn,
Expand Down