Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Python classes to pass flake8 linter #72

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 0 additions & 3 deletions freezing/sync/autolog.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import absolute_import

import inspect
import logging


Expand Down
22 changes: 21 additions & 1 deletion freezing/sync/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
import argparse
import logging

from colorlog import ColoredFormatter
from freezing.model import init_model

from freezing.sync.config import config, init_logging
from freezing.sync.exc import CommandError


class BaseCommand(metaclass=abc.ABCMeta):
"""
Base class for all command-line scripts.
"""

logger: logging.Logger = None

@property
Expand All @@ -27,6 +30,11 @@ def description(self) -> str:
"""

def build_parser(self) -> argparse.ArgumentParser:
"""
Build the argument parser for the command.

:return: The argument parser.
"""
parser = argparse.ArgumentParser(description=self.description)

log_g = parser.add_mutually_exclusive_group()
Expand Down Expand Up @@ -55,6 +63,12 @@ def build_parser(self) -> argparse.ArgumentParser:
return parser

def parse(self, args=None):
"""
Parse the command-line arguments.

:param args: The command-line arguments.
:return: The parsed arguments.
"""
parser = self.build_parser()
return parser.parse_args(args)

Expand All @@ -77,6 +91,12 @@ def init_logging(self, options):
self.logger = logging.getLogger(self.name)

def run(self, argv=None):
"""
Run the command.

:param argv: The command-line arguments.
:return:
"""
parser = self.build_parser()
assert (
parser is not None
Expand Down
10 changes: 10 additions & 0 deletions freezing/sync/cli/sync_activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ class SyncActivitiesScript(BaseCommand):
description = "Syncs all activities for registered athletes."

def build_parser(self):
"""
Build the argument parser for the command.

:return: The argument parser.
"""
parser = super(SyncActivitiesScript, self).build_parser()

parser.add_argument(
Expand Down Expand Up @@ -55,6 +60,11 @@ def build_parser(self):
return parser

def execute(self, args):
"""
Perform actual implementation for this command.

:param args: The parsed options/args from argparse.
"""
fetcher = ActivitySync(logger=self.logger)
fetcher.sync_rides(
start_date=args.start_date,
Expand Down
14 changes: 14 additions & 0 deletions freezing/sync/cli/sync_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@


class SyncActivityDetails(BaseCommand):
"""
Sync the activity details JSON.
"""

name = "sync-activity-detail"
description = "Sync the activity details JSON."

def build_parser(self):
"""
Build the argument parser for the command.

:return: The argument parser.
"""
parser = super().build_parser()
parser.add_argument(
"--athlete-id",
Expand Down Expand Up @@ -46,6 +55,11 @@ def build_parser(self):
return parser

def execute(self, args):
"""
Perform actual implementation for this command.

:param args: The parsed options/args from argparse.
"""
fetcher = ActivitySync(logger=self.logger)
fetcher.sync_rides_detail(
athlete_id=args.athlete_id,
Expand Down
9 changes: 9 additions & 0 deletions freezing/sync/cli/sync_photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@


class SyncPhotosScript(BaseCommand):
"""
Sync ride photos.
"""

name = "sync-photos"
description = "Sync ride photos."

def execute(self, args):
"""
Perform actual implementation for this command.

:param args: The parsed options/args from argparse.
"""
fetcher = PhotoSync()
fetcher.sync_photos()

Expand Down
14 changes: 14 additions & 0 deletions freezing/sync/cli/sync_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@


class SyncActivityStreams(BaseCommand):
"""
Sync activity streams.
"""

name = "sync-activity-streams"
description = "Sync activity streams."

def build_parser(self):
"""
Build the argument parser for the command.

:return: The argument parser.
"""
parser = super().build_parser()
parser.add_argument(
"--athlete-id",
Expand Down Expand Up @@ -46,6 +55,11 @@ def build_parser(self):
return parser

def execute(self, args):
"""
Perform actual implementation for this command.

:param args: The parsed options/args from argparse.
"""
fetcher = StreamSync(logger=self.logger)
fetcher.sync_streams(
athlete_id=args.athlete_id,
Expand Down
10 changes: 10 additions & 0 deletions freezing/sync/cli/sync_weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class SyncWeatherScript(BaseCommand):
description = "Sync wunderground.com weather data."

def build_parser(self):
"""
Build the argument parser for the command.

:return: The argument parser.
"""
parser = super().build_parser()

parser.add_argument(
Expand All @@ -39,6 +44,11 @@ def build_parser(self):
return parser

def execute(self, args):
"""
Perform actual implementation for this command.

:param args: The parsed options/args from argparse.
"""
fetcher = WeatherSync(logger=self.logger)
fetcher.sync_weather(
clear=args.clear, cache_only=args.cache_only, limit=args.limit
Expand Down
1 change: 0 additions & 1 deletion freezing/sync/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import arrow
import pytz
from colorlog import ColoredFormatter
from datadog import DogStatsd
from envparse import env

Expand Down
55 changes: 49 additions & 6 deletions freezing/sync/data/activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@


class ActivitySync(BaseSync):
"""
A class to synchronize activities.
"""

name = "sync-activity"
description = "Sync activities."

Expand Down Expand Up @@ -261,6 +265,15 @@ def sync_rides_detail(
use_cache: bool = True,
only_cache: bool = False,
):
"""
Synchronize ride details.

:param athlete_id: The athlete ID.
:param rewrite: Whether to rewrite the ride data already in database.
:param max_records: Limit number of rides to return.
:param use_cache: Whether to use cached activities.
:param only_cache: Whether to use only cached activities.
"""
session = meta.scoped_session()

q = session.query(Ride)
Expand Down Expand Up @@ -319,6 +332,12 @@ def sync_rides_detail(
session.rollback()

def delete_activity(self, *, athlete_id: int, activity_id: int):
"""
Delete an activity.

:param athlete_id: The athlete ID.
:param activity_id: The activity ID.
"""
session = meta.scoped_session()
ride = (
session.query(Ride)
Expand All @@ -339,6 +358,13 @@ def delete_activity(self, *, athlete_id: int, activity_id: int):
def fetch_and_store_activity_detail(
self, *, athlete_id: int, activity_id: int, use_cache: bool = False
):
"""
Fetch and store activity details.

:param athlete_id: The athlete ID.
:param activity_id: The activity ID.
:param use_cache: Whether to use cached activities.
"""
with meta.transaction_context() as session:
self.logger.info(
"Fetching detailed activity athlete_id={}, activity_id={}".format(
Expand Down Expand Up @@ -451,11 +477,10 @@ def check_activity(
"""
Asserts that activity is valid for the competition.

:param activity:
:param start_date:
:param end_date:
:param exclude_keywords:
:return:
:param activity: The activity to check.
:param start_date: The start date of the competition.
:param end_date: The end date of the competition.
:param exclude_keywords: A list of keywords to use for excluding rides from the results.
"""
assert end_date.tzinfo, "Need timezone-aware end date."
assert start_date.tzinfo, "Need timezone-aware start date"
Expand Down Expand Up @@ -519,7 +544,7 @@ def list_rides(

:param athlete: The Athlete model object.
:param start_date: The date to start listing rides.

:param end_date: The date to end listing rides.
:param exclude_keywords: A list of keywords to use for excluding rides from the results (e.g. "#NoBAFS")

:return: list of activity objects for rides in reverse chronological order.
Expand Down Expand Up @@ -658,6 +683,14 @@ def write_ride(self, activity: Activity) -> Ride:
def _sync_rides(
self, start_date: datetime, end_date: datetime, athlete, rewrite: bool = False
):
"""
Synchronize rides for an athlete.

:param start_date: The start date of the competition.
:param end_date: The end date of the competition.
:param athlete: The athlete model object.
:param rewrite: Whether to rewrite the ride data already in database.
"""
sess = meta.scoped_session()

api_ride_entries = self.list_rides(
Expand Down Expand Up @@ -794,6 +827,7 @@ def sync_rides_distributed(
end_date: datetime = None,
):
"""
Synchronize rides for a segment of athletes.

:param total_segments: The number of segments to divide athletes into (e.g. 24 if this is being run hourly)
:param segment: Which segment (0-based) to select.
Expand Down Expand Up @@ -824,6 +858,15 @@ def sync_rides(
force: bool = False,
athlete_ids: List[int] = None,
):
"""
Synchronize rides for athletes.

:param start_date: The start date of the competition.
:param end_date: The end date of the competition.
:param rewrite: Whether to rewrite the ride data already in database.
:param force: Whether to force the sync.
:param athlete_ids: List of athlete IDs to sync.
"""
with meta.transaction_context() as sess:
if start_date is None:
start_date = config.START_DATE
Expand Down
9 changes: 9 additions & 0 deletions freezing/sync/data/photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,19 @@


class PhotoSync(BaseSync):
"""
A class to synchronize photos.
"""

name = "sync-photos"
description = "Sync (non-primary) ride photos."

def sync_photos(self):
"""
Synchronize photos.

:return: None
"""
with meta.transaction_context() as sess:
q = sess.query(orm.Ride)
q = q.filter_by(photos_fetched=False, private=False)
Expand Down
20 changes: 20 additions & 0 deletions freezing/sync/data/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@


class StreamSync(BaseSync):
"""
A class to synchronize activity streams (GPS, etc.) JSON.
"""

name = "sync-activity-streams"
description = "Sync activity streams (GPS, etc.) JSON."

Expand All @@ -28,6 +32,15 @@ def sync_streams(
use_cache: bool = True,
only_cache: bool = False,
):
"""
Synchronize activity streams.

:param athlete_id: The athlete ID.
:param rewrite: Whether to rewrite the ride data already in database.
:param max_records: Limit number of rides to return.
:param use_cache: Whether to use cached activities.
:param only_cache: Whether to use only cached activities.
"""
session = meta.scoped_session()

q = session.query(Ride).options(joinedload(Ride.athlete))
Expand Down Expand Up @@ -80,6 +93,13 @@ def sync_streams(
def fetch_and_store_activity_streams(
self, *, athlete_id: int, activity_id: int, use_cache: bool = False
):
"""
Fetch and store activity streams.

:param athlete_id: The athlete ID.
:param activity_id: The activity ID.
:param use_cache: Whether to use cached activities.
"""
with meta.transaction_context() as session:
self.logger.info(
"Fetching activity streams for athlete_id={}, activity_id={}".format(
Expand Down
Loading
Loading