Fix: resolve compilation errors
- Fix screenshot capture to use correct API from screenshots library - Remove unused imports and methods - Add missing trait imports (OptionalExtension, Timelike, Hash) - Fix type conversions in database operations - Fix encryption salt conversion Compilation successful!
This commit is contained in:
parent
2d9b09b1d1
commit
df61668c79
@ -11,7 +11,7 @@ pub use entities::EntityExtractor;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Available activity categories (as per MVP spec)
|
/// Available activity categories (as per MVP spec)
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum ActivityCategory {
|
pub enum ActivityCategory {
|
||||||
Development,
|
Development,
|
||||||
Meeting,
|
Meeting,
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
/// Captures screenshots at regular intervals and collects window metadata
|
/// Captures screenshots at regular intervals and collects window metadata
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use image::{DynamicImage, ImageFormat};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::Cursor;
|
|
||||||
use crate::error::{AppError, Result};
|
use crate::error::Result;
|
||||||
|
|
||||||
pub mod screenshot;
|
pub mod screenshot;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
@ -44,19 +44,6 @@ impl CaptureData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compress image to WebP format with specified quality
|
|
||||||
pub fn compress_to_webp(image: DynamicImage, quality: u8) -> Result<Vec<u8>> {
|
|
||||||
// Convert to RGB8 for WebP encoding
|
|
||||||
let rgb_image = image.to_rgb8();
|
|
||||||
let (width, height) = rgb_image.dimensions();
|
|
||||||
|
|
||||||
// Encode to WebP
|
|
||||||
let encoder = webp::Encoder::from_rgb(&rgb_image, width, height);
|
|
||||||
let webp = encoder.encode(quality as f32);
|
|
||||||
|
|
||||||
Ok(webp.to_vec())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get file size in MB
|
/// Get file size in MB
|
||||||
pub fn size_mb(&self) -> f64 {
|
pub fn size_mb(&self) -> f64 {
|
||||||
if let Some(ref data) = self.screenshot {
|
if let Some(ref data) = self.screenshot {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
/// Screenshot capture functionality
|
/// Screenshot capture functionality
|
||||||
use crate::error::{AppError, Result};
|
use crate::error::{AppError, Result};
|
||||||
use image::DynamicImage;
|
|
||||||
use screenshots::Screen;
|
use screenshots::Screen;
|
||||||
|
|
||||||
pub struct ScreenshotCapture {
|
pub struct ScreenshotCapture {
|
||||||
@ -21,17 +20,25 @@ impl ScreenshotCapture {
|
|||||||
.ok_or_else(|| AppError::Capture("No screens available".to_string()))?;
|
.ok_or_else(|| AppError::Capture("No screens available".to_string()))?;
|
||||||
|
|
||||||
// Capture screenshot
|
// Capture screenshot
|
||||||
let image_buf = screen.capture()
|
let image = screen.capture()
|
||||||
.map_err(|e| AppError::Capture(format!("Failed to capture screenshot: {}", e)))?;
|
.map_err(|e| AppError::Capture(format!("Failed to capture screenshot: {}", e)))?;
|
||||||
|
|
||||||
// Convert to DynamicImage
|
// Get dimensions and convert to RGB
|
||||||
let dynamic_image = DynamicImage::ImageRgba8(image_buf);
|
let width = image.width() as u32;
|
||||||
|
let height = image.height() as u32;
|
||||||
|
|
||||||
// Compress to WebP
|
// Convert RGBA to RGB (screenshots library returns RGBA)
|
||||||
let rgb_image = dynamic_image.to_rgb8();
|
let rgba_data = image.rgba();
|
||||||
let (width, height) = rgb_image.dimensions();
|
let mut rgb_data = Vec::with_capacity((width * height * 3) as usize);
|
||||||
|
|
||||||
let encoder = webp::Encoder::from_rgb(&rgb_image, width, height);
|
for chunk in rgba_data.chunks(4) {
|
||||||
|
rgb_data.push(chunk[0]); // R
|
||||||
|
rgb_data.push(chunk[1]); // G
|
||||||
|
rgb_data.push(chunk[2]); // B
|
||||||
|
// Skip alpha channel
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoder = webp::Encoder::from_rgb(&rgb_data, width, height);
|
||||||
let webp = encoder.encode(quality as f32);
|
let webp = encoder.encode(quality as f32);
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
use super::{DailyReport, ReportMetadata, Period, Activity, Statistics, CategoryStats, Entities, Screenshot};
|
use super::{DailyReport, ReportMetadata, Period, Activity, Statistics, CategoryStats, Entities, Screenshot};
|
||||||
use crate::storage::{Database, StoredCapture};
|
use crate::storage::{Database, StoredCapture};
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{Utc, Timelike};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct ReportGenerator {
|
pub struct ReportGenerator {
|
||||||
@ -57,8 +57,6 @@ impl ReportGenerator {
|
|||||||
/// Convert stored captures to activities
|
/// Convert stored captures to activities
|
||||||
fn captures_to_activities(&self, captures: Vec<StoredCapture>) -> Vec<Activity> {
|
fn captures_to_activities(&self, captures: Vec<StoredCapture>) -> Vec<Activity> {
|
||||||
let mut activities = Vec::new();
|
let mut activities = Vec::new();
|
||||||
let mut tool_accumulator: HashMap<String, Vec<String>> = HashMap::new();
|
|
||||||
let mut lang_accumulator: HashMap<String, Vec<String>> = HashMap::new();
|
|
||||||
|
|
||||||
for capture in captures {
|
for capture in captures {
|
||||||
let duration = 300; // 5 minutes default (capture interval)
|
let duration = 300; // 5 minutes default (capture interval)
|
||||||
|
|||||||
@ -12,7 +12,6 @@ pub use export::JsonExporter;
|
|||||||
use chrono::{DateTime, Utc, Duration};
|
use chrono::{DateTime, Utc, Duration};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::analysis::ActivityCategory;
|
|
||||||
|
|
||||||
/// Daily activity report
|
/// Daily activity report
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/// Database operations with SQLite
|
/// Database operations with SQLite
|
||||||
use rusqlite::{params, Connection, Row};
|
use rusqlite::{params, Connection, Row, OptionalExtension};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use sha2::{Sha256, Digest};
|
use sha2::{Sha256, Digest};
|
||||||
@ -36,7 +36,7 @@ impl Database {
|
|||||||
.map_err(|e| AppError::Storage(format!("Failed to start transaction: {}", e)))?;
|
.map_err(|e| AppError::Storage(format!("Failed to start transaction: {}", e)))?;
|
||||||
|
|
||||||
// Insert window metadata
|
// Insert window metadata
|
||||||
let window_id: i64 = tx.execute(
|
tx.execute(
|
||||||
"INSERT INTO windows (title, process_name, process_id, is_active, timestamp)
|
"INSERT INTO windows (title, process_name, process_id, is_active, timestamp)
|
||||||
VALUES (?1, ?2, ?3, ?4, ?5)",
|
VALUES (?1, ?2, ?3, ?4, ?5)",
|
||||||
params![
|
params![
|
||||||
@ -208,7 +208,7 @@ impl Database {
|
|||||||
/// Cleanup old data based on retention policy
|
/// Cleanup old data based on retention policy
|
||||||
pub fn cleanup_old_data(&mut self, retention_days: i64) -> Result<usize> {
|
pub fn cleanup_old_data(&mut self, retention_days: i64) -> Result<usize> {
|
||||||
let query = cleanup_old_data_query(retention_days);
|
let query = cleanup_old_data_query(retention_days);
|
||||||
let deleted = self.conn.execute_batch(&query)
|
self.conn.execute_batch(&query)
|
||||||
.map_err(|e| AppError::Storage(format!("Failed to cleanup old data: {}", e)))?;
|
.map_err(|e| AppError::Storage(format!("Failed to cleanup old data: {}", e)))?;
|
||||||
|
|
||||||
log::info!("Cleaned up data older than {} days", retention_days);
|
log::info!("Cleaned up data older than {} days", retention_days);
|
||||||
|
|||||||
@ -22,7 +22,7 @@ impl Encryptor {
|
|||||||
pub fn from_password(password: &str) -> Result<Self> {
|
pub fn from_password(password: &str) -> Result<Self> {
|
||||||
// Generate random salt
|
// Generate random salt
|
||||||
let salt = SaltString::generate(&mut OsRng);
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
let key = Self::derive_key(password, salt.as_bytes())?;
|
let key = Self::derive_key(password, salt.as_str().as_bytes())?;
|
||||||
|
|
||||||
let cipher = Aes256Gcm::new_from_slice(&key)
|
let cipher = Aes256Gcm::new_from_slice(&key)
|
||||||
.map_err(|e| AppError::Encryption(format!("Failed to create cipher: {}", e)))?;
|
.map_err(|e| AppError::Encryption(format!("Failed to create cipher: {}", e)))?;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user