def _determine_ring_distance(self, max_length: pint.quantity.Quantity) -> typing.Optional[pint.quantity.Quantity]: ring_distance = None if self.poster.units == "metric": unit = Units().km else: unit = Units().mile for distance in [1.0 * unit, 5.0 * unit, 10.0 * unit, 50.0 * unit]: if max_length < distance: continue ring_distance = distance if (max_length / distance) <= 5: break return ring_distance
def fixture_mock_track_instance(mocker: MockerFixture) -> MagicMock: mock_track_class = mocker.patch("gpxtrackposter.track_loader.Track") instance = mock_track_class.return_value instance.length.return_value = 1 * Units().km instance.start_time.return_value = datetime.datetime.now() instance.end_time.return_value = datetime.datetime.now() return instance
def fetch_args(self, args: argparse.Namespace) -> None: """Get arguments from the parser""" self._rings = args.circular_rings self._ring_color = args.circular_ring_color if args.circular_ring_max_distance: self._max_distance = abs( args.circular_ring_max_distance) * Units().km
def __init__(self) -> None: self._min_length: pint.quantity.Quantity = 1 * Units().km self.special_file_names: typing.List[str] = [] self.year_range = YearRange() self.cache_dir: typing.Optional[str] = None self.strava_cache_file = "" self._cache_file_names: typing.Dict[str, str] = {}
def __init__(self, workers: typing.Optional[int]) -> None: self._workers = workers self._min_length: pint.quantity.Quantity = 1 * Units().km self.special_file_names: typing.List[str] = [] self.year_range = YearRange() self.cache_dir: typing.Optional[str] = None self.strava_cache_file = "" self._cache_file_names: typing.Dict[str, str] = {} self._activity_type: str = "all"
def _compute_track_statistics( self, ) -> typing.Tuple[pint.quantity.Quantity, pint.quantity.Quantity, QuantityRange, int]: length_range = QuantityRange() total_length = 0.0 * Units().meter self.total_length_year_dict.clear() weeks = {} for t in self.tracks: total_length += t.length() self.total_length_year_dict[t.start_time().year] += t.length() length_range.extend(t.length()) # time.isocalendar()[1] -> week number weeks[(t.start_time().year, t.start_time().isocalendar()[1])] = 1 return ( total_length, total_length / len(self.tracks), length_range, len(weeks), )
def length(self) -> pint.quantity.Quantity: return self._length_meters * Units().meter
def main() -> None: """Handle command line arguments and call other modules as needed.""" p = poster.Poster() drawers = { "grid": grid_drawer.GridDrawer(p), "calendar": calendar_drawer.CalendarDrawer(p), "heatmap": heatmap_drawer.HeatmapDrawer(p), "circular": circular_drawer.CircularDrawer(p), "github": github_drawer.GithubDrawer(p), } args_parser = argparse.ArgumentParser(prog=__app_name__) args_parser.add_argument( "--gpx-dir", dest="gpx_dir", metavar="DIR", type=str, default=".", help="Directory containing GPX files (default: current directory).", ) args_parser.add_argument( "--output", metavar="FILE", type=str, default="poster.svg", help='Name of generated SVG image file (default: "poster.svg").', ) args_parser.add_argument( "--language", metavar="LANGUAGE", type=str, default="", help="Language (default: english).", ) args_parser.add_argument( "--localedir", metavar="DIR", type=str, help= "The directory where the translation files can be found (default: the system's locale directory).", ) args_parser.add_argument( "--year", metavar="YEAR", type=str, default="all", help= 'Filter tracks by year; "NUM", "NUM-NUM", "all" (default: all years)', ) args_parser.add_argument("--title", metavar="TITLE", type=str, help="Title to display.") args_parser.add_argument( "--athlete", metavar="NAME", type=str, default="John Doe", help='Athlete name to display (default: "John Doe").', ) args_parser.add_argument( "--special", metavar="FILE", action="append", default=[], help= "Mark track file from the GPX directory as special; use multiple times to mark " "multiple tracks.", ) types = '", "'.join(drawers.keys()) args_parser.add_argument( "--type", metavar="TYPE", default="grid", choices=drawers.keys(), help= f'Type of poster to create (default: "grid", available: "{types}").', ) args_parser.add_argument( "--background-color", dest="background_color", metavar="COLOR", type=str, default="#222222", help='Background color of poster (default: "#222222").', ) args_parser.add_argument( "--track-color", dest="track_color", metavar="COLOR", type=str, default="#4DD2FF", help='Color of tracks (default: "#4DD2FF").', ) args_parser.add_argument( "--track-color2", dest="track_color2", metavar="COLOR", type=str, help="Secondary color of tracks (default: none).", ) args_parser.add_argument( "--text-color", dest="text_color", metavar="COLOR", type=str, default="#FFFFFF", help='Color of text (default: "#FFFFFF").', ) args_parser.add_argument( "--special-color", dest="special_color", metavar="COLOR", default="#FFFF00", help='Special track color (default: "#FFFF00").', ) args_parser.add_argument( "--special-color2", dest="special_color2", metavar="COLOR", help="Secondary color of special tracks (default: none).", ) args_parser.add_argument( "--units", dest="units", metavar="UNITS", type=str, choices=["metric", "imperial"], default="metric", help='Distance units; "metric", "imperial" (default: "metric").', ) args_parser.add_argument( "--clear-cache", dest="clear_cache", action="store_true", help="Clear the track cache.", ) args_parser.add_argument( "--from-strava", dest="from_strava", metavar="FILE", type=str, help="strava config file", ) args_parser.add_argument("--verbose", dest="verbose", action="store_true", help="Verbose logging.") args_parser.add_argument("--logfile", dest="logfile", metavar="FILE", type=str) args_parser.add_argument( "--special-distance", dest="special_distance", metavar="DISTANCE", type=float, default=10.0, help="Special Distance1 by km and color with the special_color", ) args_parser.add_argument( "--special-distance2", dest="special_distance2", metavar="DISTANCE", type=float, default=20.0, help="Special Distance2 by km and corlor with the special_color2", ) args_parser.add_argument( "--min-distance", dest="min_distance", metavar="DISTANCE", type=float, default=1.0, help="min distance by km for track filter", ) for _, drawer in drawers.items(): drawer.create_args(args_parser) args = args_parser.parse_args() for _, drawer in drawers.items(): drawer.fetch_args(args) log = logging.getLogger("gpxtrackposter") log.setLevel(logging.INFO if args.verbose else logging.ERROR) if args.logfile: handler = logging.FileHandler(args.logfile) log.addHandler(handler) loader = track_loader.TrackLoader() loader.set_cache_dir( os.path.join(appdirs.user_cache_dir(__app_name__, __app_author__), "tracks")) if not loader.year_range.parse(args.year): raise ParameterError(f"Bad year range: {args.year}.") loader.special_file_names = args.special loader.set_min_length(args.min_distance * Units().km) if args.clear_cache: print("Clearing cache...") loader.clear_cache() if args.from_strava: tracks = loader.load_strava_tracks(args.from_strava) else: tracks = loader.load_tracks(args.gpx_dir) if not tracks: if not args.clear_cache: print("No tracks found.") return print( f"Creating poster of type {args.type} with {len(tracks)} tracks and storing it in file {args.output}..." ) p.set_language(args.language, args.localedir) p.set_athlete(args.athlete) p.set_title(args.title if args.title else p.translate("MY TRACKS")) p.special_distance = { "special_distance": args.special_distance * Units().km, "special_distance2": args.special_distance2 * Units().km, } p.colors = { "background": args.background_color, "track": args.track_color, "track2": args.track_color2 or args.track_color, "special": args.special_color, "special2": args.special_color2 or args.special_color, "text": args.text_color, } p.units = args.units p.set_tracks(tracks) if args.type == "github": p.height = 55 + p.years.count() * 43 p.draw(drawers[args.type], args.output)
def m2u(self, m: pint.quantity.Quantity) -> float: """Convert meters to kilometers or miles, according to units.""" if self.units == "metric": return m.m_as(Units().km) return m.m_as(Units().mile)