-
-
Notifications
You must be signed in to change notification settings - Fork 313
Fix/GitHub badge issue #3226 #4629
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
Fix/GitHub badge issue #3226 #4629
Conversation
β¦x for badge bar design
β¦e raw count. Fixed some minor typos and added comments for the repo badge class
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughUpdated ProjectBadgeView and RepoBadgeView to compute 30βday uniqueβvisit badges (distinct IPs), include zeroβvisit days in the 30βday sequence, and adjust PNG chart rendering (fixed 30βbar layout, reserved title area, grid/bar/text placement, and font fallback). No-cache headers unchanged; class docstrings added. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant V as Project/RepoBadgeView
participant DB as Visits Store
participant R as Chart Renderer
C->>V: GET /badge.png
activate V
V->>DB: Query visits for last 30 days
DB-->>V: Visit records (timestamps, IPs)
V->>V: Aggregate distinct IPs per day, fill zeros to 30-day sequence
V->>R: Prepare chart data (30 bars, title area, spacing)
R-->>V: PNG image (bars, grid, totals, fonts with fallback)
V-->>C: 200 OK (PNG, Cache-Control: no-cache)
deactivate V
Estimated code review effortπ― 3 (Moderate) | β±οΈ ~20 minutes Pre-merge checks and finishing touchesβ Failed checks (1 warning, 1 inconclusive)
β Passed checks (1 passed)
β¨ Finishing touches
π§ͺ Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
π§Ή Nitpick comments (1)
website/views/project.py (1)
1898-1985: Consider extracting common badge generation logic.The badge generation code in
RepoBadgeViewis nearly identical toProjectBadgeView(lines 169-253). Both classes implement the same chart rendering logic with only minor differences (project vs. repo objects).Consider extracting the common badge generation logic into a shared helper method or base class to improve maintainability and reduce duplication. This would make future updates (like color schemes or layout changes) easier to apply consistently.
Example approach:
- Create a
_generate_badge_imagehelper method that accepts visit data and total count- Both view classes call this helper with their respective data
- Reduces ~100 lines of duplicated code
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
π Files selected for processing (1)
website/views/project.py(7 hunks)
π§° Additional context used
πͺ Ruff (0.14.0)
website/views/project.py
203-203: Local variable text_color is assigned to but never used
Remove assignment to unused variable text_color
(F841)
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
π Additional comments (6)
website/views/project.py (6)
123-125: LGTM! Clear documentation.The class docstring accurately describes the badge's purpose and key feature (30-day unique visits with zero-day visualization).
206-220: LGTM! Chart dimensions correctly adjusted for 30 bars.The bar width and spacing calculations properly accommodate 30 bars:
bar_width = chart_width / 32accounts for 30 bars plus margin spacebar_spacing = chart_width / 30provides even distribution
227-242: LGTM! Zero-day visualization implemented correctly.The faint bar color (
#fcbab3) effectively indicates days with zero visits, preventing confusion about missing data.
243-253: LGTM! Text positioning prevents overlap.Centering the title at y=15 with reserved space (text_height=50) ensures no overlap with the chart bars.
1851-1853: LGTM! Clear documentation.The class docstring accurately describes the badge's purpose, matching ProjectBadgeView's documentation style.
169-192: Verify IP model and unique address counting
Confirm that theIPmodel defines anaddressfield and thatCount("address", distinct=True)correctly counts unique daily visitors. For example, run:rg -nP 'class\s+IP' -C3 rg -n 'address' -C2
|
fix the |
yes doing that, thankyou for the suggestion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
π§Ή Nitpick comments (3)
website/views/project.py (3)
122-265: Consider extracting common badge generation logic.Both
ProjectBadgeViewandRepoBadgeViewcontain nearly identical code (~140 lines each) with only minor differences (model type and field names). This duplication violates the DRY principle and creates maintenance burden.Consider extracting the common badge generation logic into a helper function or base class:
class BaseBadgeView(APIView): """Base class for generating visit badges.""" model_class = None # Override in subclass count_field = None # Override in subclass def get_client_ip(self, request): # ... (current implementation) ... def generate_badge(self, obj, request): # ... (common badge generation logic) ... def get(self, request, slug): obj = get_object_or_404(self.model_class, slug=slug) # ... (IP tracking logic) ... return self.generate_badge(obj, request) class ProjectBadgeView(BaseBadgeView): """Generates a 30-day unique visits badge PNG for a Project.""" model_class = Project count_field = 'project_visit_count' class RepoBadgeView(BaseBadgeView): """Generates a 30-day unique visits badge PNG for a Repo.""" model_class = Repo count_field = 'repo_visit_count'This refactor would eliminate duplication, reduce the risk of divergence, and simplify future maintenance.
Also applies to: 1850-1998
145-145: Clarify or remove unclear comment.The comment "(original case-sensitive lookup)" is unclear. It doesn't explain why this is noted or what alternative was considered. If case-sensitivity was intentionally preserved, consider clarifying why; otherwise, remove the comment.
206-221: Consider extracting magic numbers as constants.Several hardcoded values reduce code maintainability:
28(font size)15(text y position)50(text height)40(margin)32,30(bar calculations)Consider extracting these as class-level constants:
class ProjectBadgeView(APIView): # Badge dimensions BADGE_WIDTH = 600 BADGE_HEIGHT = 200 MARGIN = 40 TEXT_HEIGHT = 50 FONT_SIZE = 28 TEXT_Y_POSITION = 15 # Bar calculations BAR_COUNT = 30 BAR_WIDTH_DIVISOR = 32 # 30 bars + 2 for margins # Colors BAR_COLOR = "#e05d44" FAINT_COLOR = "#fcbab3" GRID_COLOR = "#eeeeee"This would make the code more maintainable and self-documenting.
Also applies to: 1936-1951
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
π Files selected for processing (1)
website/views/project.py(7 hunks)
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
π Additional comments (6)
website/views/project.py (6)
123-125: LGTM! Clear docstrings added.The docstrings accurately describe the badge generation functionality and the zero-day visualization feature.
Also applies to: 1851-1853
170-178: LGTM! 30-day window and unique IP counting implemented correctly.The changes properly extend the tracking window to 30 days and use
distinct=Trueto count unique IP addresses per day rather than total visits. This aligns with the PR objectives and provides more meaningful visitor metrics.Also applies to: 1899-1907
183-193: LGTM! Zero-visit days correctly included in sequence.The logic properly builds a complete 30-day sequence by iterating through each day and defaulting to 0 visits when no data exists. The calculation
today - timedelta(days=29-i)correctly generates dates from 30 days ago to today in chronological order.Also applies to: 1912-1923
206-221: LGTM! Chart layout and bar calculations are correct.The reserved
text_height = 50prevents title-bar overlap, and the bar width/spacing calculations (chart_width/32andchart_width/30respectively) correctly render 30 bars with consistent spacing. The narrower bar width creates visual gaps between bars, which appears intentional for clarity.Also applies to: 1936-1951
227-241: LGTM! Zero-day visualization implemented effectively.The bar rendering correctly handles both cases: proportional bars for non-zero visits and minimal faint bars (
#fcbab3color) for zero-visit days. This provides clear visual feedback for the complete 30-day period.Also applies to: 1957-1971
243-253: LGTM! Text positioning prevents overlap.The centered text at
y=15with font size 28 fits comfortably within the reservedtext_height=50area. Bars begin aty=90(margin + text_height), ensuring no overlap with the title.Also applies to: 1973-1985
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Addresses the GitHub badge rendering issues by moving from a 7-day to a 30-day view and improving chart layout and clarity.
- Extends data window to 30 days and counts distinct IPs per day.
- Reworks bar sizing/spacing and adds faint bars for zero-visit days to avoid gaps.
- Repositions title text and simplifies rendering (solid rectangles instead of gradients) for better performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
π§Ή Nitpick comments (1)
website/views/project.py (1)
196-265: Consider extracting shared chart rendering logic to reduce duplication.The chart rendering logic (lines 196-265 and 1926-1998) is nearly identical between
ProjectBadgeViewandRepoBadgeView, with only minor differences in the visit count field accessed. Consider extracting a shared helper function (e.g.,build_badge_image(dates, counts, total_views, width, height)) to improve maintainability and reduce the risk of future drift between the two implementations. Additionally, promoting magic numbers likeCHART_DAYS = 30,BAR_WIDTH_DIVISOR = 32,BAR_SPACING_DIVISOR = 30, andTEXT_HEIGHT = 50to module-level constants would improve readability.Example refactoring:
# Module-level constants CHART_DAYS = 30 BAR_WIDTH_DIVISOR = 32 BAR_SPACING_DIVISOR = 30 TEXT_HEIGHT = 50 BAR_COLOR = "#e05d44" GRID_COLOR = "#eeeeee" FAINT_BAR_COLOR = "#fcbab3" def build_badge_image(dates, counts, total_views, width=600, height=200): """ Build a badge image with a 30-day chart. Args: dates: List of dates counts: List of visit counts per date total_views: Total view count to display width: Image width in pixels height: Image height in pixels Returns: BytesIO buffer containing the PNG image """ img = Image.new("RGB", (width, height), color="white") draw = ImageDraw.Draw(img) margin = 40 chart_width = width - 2 * margin chart_height = height - 2 * margin - TEXT_HEIGHT # Calculate max count and bar dimensions max_count = max(counts) if counts and max(counts) > 0 else 1 bar_width = chart_width / BAR_WIDTH_DIVISOR bar_spacing = chart_width / BAR_SPACING_DIVISOR # Draw grid lines for i in range(5): y = margin + TEXT_HEIGHT + (chart_height * i) // 4 draw.line([(margin, y), (width - margin, y)], fill=GRID_COLOR) # Draw bars if dates and counts: for i, count in enumerate(counts): x1 = margin + (i * bar_spacing) x2 = x1 + bar_width if count > 0: bar_height = (count / max_count) * chart_height y1 = height - margin - bar_height y2 = height - margin draw.rectangle([(x1, y1), (x2, y2)], fill=BAR_COLOR) else: faint_color = FAINT_BAR_COLOR y1 = y2 = height - margin - 2 draw.rectangle([(x1, y1), (x2, y2 + 1)], fill=faint_color) # Draw title text try: font = ImageFont.truetype("DejaVuSans.ttf", 28) except OSError: font = ImageFont.load_default() text = f"Total Views: {total_views}" text_bbox = draw.textbbox((0, 0), text, font=font) text_width = text_bbox[2] - text_bbox[0] text_x = (width - text_width) // 2 text_y = 15 draw.text((text_x, text_y), text, font=font, fill=BAR_COLOR) # Save to buffer buffer = BytesIO() img.save(buffer, format="PNG", optimize=True, compress_level=9) buffer.seek(0) return bufferThen both views would simply call:
buffer = build_badge_image(dates, counts, total_views)Also applies to: 1926-1998
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
π Files selected for processing (1)
website/views/project.py(6 hunks)
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
π Additional comments (12)
website/views/project.py (12)
123-125: LGTM!The docstring clearly describes the badge's purpose and behavior.
170-193: LGTM! 30-day window and unique IP counting are correct.The calculation correctly retrieves 30 days of data (today minus 29 days through today) and properly counts distinct IPs. The zero-day padding logic ensures all 30 days are represented in the chart.
202-220: LGTM! Chart layout calculations are correct.The reserved title space (50px), bar width (chart_width/32), and bar spacing (chart_width/30) calculations properly accommodate 30 bars with appropriate margins.
222-241: LGTM! Grid and bar rendering logic is correct.The grid lines are properly offset for the reserved title space, and the bar rendering correctly handles both non-zero days (proportional bars) and zero days (faint 2px bars).
243-253: LGTM! Text rendering is correct.The text is properly centered, positioned at the top within the reserved space, and uses an appropriate font size.
257-257: LGTM! PNG optimization is correct.Using
optimize=Trueandcompress_level=9are appropriate for PNG format and improve performance as intended.
1851-1853: LGTM!The docstring clearly describes the badge's purpose and behavior for repositories.
1899-1923: LGTM! 30-day window and unique IP counting are correct.The calculation correctly retrieves 30 days of data and properly counts distinct IPs, mirroring the ProjectBadgeView implementation.
1936-1951: LGTM! Chart layout calculations are correct.The layout calculations properly mirror the ProjectBadgeView implementation with appropriate spacing and margins.
1952-1971: LGTM! Grid and bar rendering logic is correct.The rendering logic properly handles both non-zero and zero-day bars, consistent with the ProjectBadgeView implementation.
1973-1985: LGTM! Text rendering is correct.The text is properly centered and positioned to avoid overlapping with the chart bars.
1989-1989: LGTM! PNG optimization is correct.The PNG save options properly use
optimize=Trueandcompress_level=9for efficient output.
|
@DonnieBLT this |
Fix GitHub Badge Issue - Improve Chart Visualization and Data Range
Issue: the github badge is not looking right fixes #3226
Description
This PR addresses several issues with the GitHub badge charts for both
RepoBadgeViewandProjectBadgeView:Modified Files:
website/views/project.py- Updated bothRepoBadgeViewandProjectBadgeViewclassesKey Improvements:
seven_days_agotothirty_days_agochart_width / 32for 30 bars#fcbab3) for days with no visitstext_height = 50pxto prevent title overlapdistinct=Truefor accurate IP countingBefore/After
Before: Inconsistent spacing, overlapping, random bar size, 7-day window, missing zero-day indicators (image shared)
After: Professional 30-bar chart with proper spacing, no overlapping, consistent bar size and zero-day visualization (image shared)
Impact
This fix significantly improves the visual quality and usefulness of GitHub badges:
Checklist
RepoBadgeViewandProjectBadgeViewAdditional Notes
The changes maintain backward compatibility while significantly improving the badge quality. The 30-day window provides more meaningful trend data for repository activity tracking.
Summary by CodeRabbit