maziggy 4 месяцев назад
Родитель
Сommit
4f2fa7685a

+ 15 - 1
backend/app/services/telemetry.py

@@ -6,10 +6,11 @@ import uuid
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
 
 
 import httpx
 import httpx
-from sqlalchemy import select
+from sqlalchemy import func, select
 from sqlalchemy.ext.asyncio import AsyncSession
 from sqlalchemy.ext.asyncio import AsyncSession
 
 
 from backend.app.core.config import APP_VERSION
 from backend.app.core.config import APP_VERSION
+from backend.app.models.printer import Printer
 from backend.app.models.settings import Settings
 from backend.app.models.settings import Settings
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
@@ -63,6 +64,17 @@ async def get_telemetry_url(db: AsyncSession) -> str:
     return setting.value if setting else DEFAULT_TELEMETRY_URL
     return setting.value if setting else DEFAULT_TELEMETRY_URL
 
 
 
 
+async def get_printer_model_counts(db: AsyncSession) -> dict[str, int]:
+    """Get count of each printer model configured in BamBuddy."""
+    result = await db.execute(select(Printer.model, func.count(Printer.id)).group_by(Printer.model))
+    counts = {}
+    for model, count in result.all():
+        # Normalize model name (handle None/empty)
+        model_name = model if model else "Unknown"
+        counts[model_name] = count
+    return counts
+
+
 async def send_heartbeat(db: AsyncSession) -> bool:
 async def send_heartbeat(db: AsyncSession) -> bool:
     """Send anonymous heartbeat to telemetry server."""
     """Send anonymous heartbeat to telemetry server."""
     global _last_heartbeat
     global _last_heartbeat
@@ -80,6 +92,7 @@ async def send_heartbeat(db: AsyncSession) -> bool:
 
 
         installation_id = await get_or_create_installation_id(db)
         installation_id = await get_or_create_installation_id(db)
         telemetry_url = await get_telemetry_url(db)
         telemetry_url = await get_telemetry_url(db)
+        printer_models = await get_printer_model_counts(db)
 
 
         async with httpx.AsyncClient(timeout=10.0) as client:
         async with httpx.AsyncClient(timeout=10.0) as client:
             response = await client.post(
             response = await client.post(
@@ -87,6 +100,7 @@ async def send_heartbeat(db: AsyncSession) -> bool:
                 json={
                 json={
                     "installation_id": installation_id,
                     "installation_id": installation_id,
                     "version": APP_VERSION,
                     "version": APP_VERSION,
+                    "printer_models": printer_models,
                 },
                 },
             )
             )
             response.raise_for_status()
             response.raise_for_status()

+ 5 - 4
frontend/src/i18n/locales/en.ts

@@ -247,14 +247,15 @@ export default {
     telemetryDescription: 'Help improve BamBuddy by sending anonymous usage data',
     telemetryDescription: 'Help improve BamBuddy by sending anonymous usage data',
     telemetryLearnMore: 'Learn more',
     telemetryLearnMore: 'Learn more',
     telemetryInfoTitle: 'What data is collected?',
     telemetryInfoTitle: 'What data is collected?',
-    telemetryInfoIntro: 'BamBuddy collects minimal anonymous data to help understand how many people use the app and which versions are in use. This helps prioritize bug fixes and new features.',
+    telemetryInfoIntro: 'BamBuddy collects minimal anonymous data to help understand how many people use the app, which versions and printer models are in use. This helps prioritize bug fixes and new features.',
     telemetryInfoCollected: 'What we collect:',
     telemetryInfoCollected: 'What we collect:',
     telemetryInfoItem1: 'A random installation ID (not linked to you or your hardware)',
     telemetryInfoItem1: 'A random installation ID (not linked to you or your hardware)',
     telemetryInfoItem2: 'The app version you\'re running',
     telemetryInfoItem2: 'The app version you\'re running',
-    telemetryInfoItem3: 'A timestamp (to count daily/weekly active users)',
+    telemetryInfoItem3: 'Printer model types (e.g., X1C, P1S) - not names or serial numbers',
+    telemetryInfoItem4: 'A timestamp (to count daily/weekly active users)',
     telemetryInfoNotCollected: 'What we do NOT collect:',
     telemetryInfoNotCollected: 'What we do NOT collect:',
-    telemetryInfoNotItem1: 'IP addresses or location data',
-    telemetryInfoNotItem2: 'Printer names, serial numbers, or any printer data',
+    telemetryInfoNotItem1: 'Your IP address is hashed and cannot be reversed',
+    telemetryInfoNotItem2: 'Printer names, serial numbers, or access codes',
     telemetryInfoNotItem3: 'Print history, filenames, or any personal content',
     telemetryInfoNotItem3: 'Print history, filenames, or any personal content',
     telemetryInfoNotItem4: 'Any information that could identify you',
     telemetryInfoNotItem4: 'Any information that could identify you',
     telemetryInfoFooter: 'You can disable telemetry at any time. The installation ID is randomly generated and cannot be traced back to you.',
     telemetryInfoFooter: 'You can disable telemetry at any time. The installation ID is randomly generated and cannot be traced back to you.',

+ 4 - 0
frontend/src/pages/SettingsPage.tsx

@@ -2174,6 +2174,10 @@ export function SettingsPage() {
                     <CheckCircle className="w-4 h-4 text-bambu-green mt-0.5 shrink-0" />
                     <CheckCircle className="w-4 h-4 text-bambu-green mt-0.5 shrink-0" />
                     <span>{t('settings.telemetryInfoItem3')}</span>
                     <span>{t('settings.telemetryInfoItem3')}</span>
                   </li>
                   </li>
+                  <li className="flex items-start gap-2 text-bambu-gray">
+                    <CheckCircle className="w-4 h-4 text-bambu-green mt-0.5 shrink-0" />
+                    <span>{t('settings.telemetryInfoItem4')}</span>
+                  </li>
                 </ul>
                 </ul>
               </div>
               </div>
 
 

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-DO8dvHhf.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
 
     <!-- Splash screens for iOS -->
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-BuRs1RuZ.js"></script>
+    <script type="module" crossorigin src="/assets/index-DO8dvHhf.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-DgCUmTZF.css">
     <link rel="stylesheet" crossorigin href="/assets/index-DgCUmTZF.css">
   </head>
   </head>
   <body>
   <body>

+ 5 - 0
update_website_wiki.sh

@@ -1,5 +1,10 @@
 #!/bin/bash
 #!/bin/bash
 
 
+cd ../bambuddy-telemetry
+git add .
+git commit -m "Updated telemetry"
+git push
+
 cd ../bambuddy-website
 cd ../bambuddy-website
 git add .
 git add .
 git commit -m "Updated website"
 git commit -m "Updated website"

Некоторые файлы не были показаны из-за большого количества измененных файлов