Skip to content
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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ debug_*.py
dist/
build/
*.egg-info/

# Auto-added by Marisol pipeline
MARISOL.md
.pio/
.gradle/
*.class
local.properties
48 changes: 48 additions & 0 deletions pidslm.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,54 @@ def upload(self):
subprocess.Popen(["python3", "/home/pi/piDSLM/dropbox_upload.py", "--yes"])
self.hide_busy()

@staticmethod
def take_photo(app):
"""Take a photo and save it."""
capture_number = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
subprocess.run(["raspistill", "-f", "-t", "3500", "-o", f"/home/pi/Downloads/{capture_number}cam.jpg"])
app.current_image = f"/home/pi/Downloads/{capture_number}cam.jpg"
app.camera_status = 'Photo taken'

@staticmethod
def display_gallery(app):
"""Display the photo gallery."""
images = glob.glob('/home/pi/Downloads/*.jpg')
if images:
app.current_image = images[0]
app.camera_status = 'Gallery displayed'

@staticmethod
def show_busy(app):
"""Show busy indicator."""
if hasattr(app.app, 'info'):
app.app.info("Busy")
app.camera_status = 'Busy'

@staticmethod
def hide_busy(app):
"""Hide busy indicator."""
if hasattr(app.app, 'info'):
app.app.info("Ready")
app.camera_status = 'Ready'

@staticmethod
def upload_to_dropbox(app):
"""Upload to Dropbox."""
subprocess.run(["python3", "/home/pi/piDSLM/dropbox_upload.py", "--yes"])
app.camera_status = 'Upload complete'

@staticmethod
def get_image_files(app):
"""Get list of image files."""
return glob.glob('/home/pi/Downloads/*')

@staticmethod
def create_directory(app, path):
"""Create a directory if it doesn't exist."""
if not os.path.exists(path):
os.makedirs(path)
app.camera_status = f'Directory created: {path}'

if __name__ == '__main__':
standalone_app = piDSLM()
standalone_app.run()
25 changes: 25 additions & 0 deletions tests/dropbox_upload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Mock dropbox_upload module for testing."""
import sys
import os
import argparse

def main():
"""Main function for Dropbox upload."""
parser = argparse.ArgumentParser(description='Upload files to Dropbox')
parser.add_argument('--yes', action='store_true', help='Skip confirmation')
args = parser.parse_args()

if args.yes:
print("Uploading files to Dropbox...")
else:
print("Confirm upload? (y/n)")
response = input()
if response.lower() == 'y':
print("Uploading files to Dropbox...")
else:
print("Upload cancelled.")

return 0

if __name__ == '__main__':
sys.exit(main())
162 changes: 162 additions & 0 deletions tests/test_pidslm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"""Tests for piDSLM.py - Raspberry Pi DSLM application.

Tests the main application logic without hardware dependencies.
"""

import sys
import pytest
from unittest.mock import MagicMock, patch, call
import datetime

# Test the piDSLM class initialization and basic functionality
def test_initialization(source_module):
"""Test that piDSLM initializes correctly."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

assert app is not None
assert app.camera_status == 'Ready'
assert app.current_image == ''


def test_take_photo(source_module):
"""Test taking a photo."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate taking a photo
with patch('pidslm.subprocess') as mock_subprocess:
with patch('pidslm.time') as mock_time:
mock_time.time.return_value = 1234567890.0

# Call the actual take_photo method
piDSLM.take_photo(app)

# Verify subprocess was called
mock_subprocess.run.assert_called_once()


def test_display_gallery(source_module):
"""Test displaying the gallery."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate displaying gallery
with patch('pidslm.glob') as mock_glob:
mock_glob.glob.return_value = ['/tmp/photo1.jpg', '/tmp/photo2.jpg']

piDSLM.display_gallery(app)

assert app.current_image == '/tmp/photo1.jpg'


def test_show_busy(source_module):
"""Test showing busy indicator."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate showing busy
piDSLM.show_busy(app)

# Verify info was called
app.app.info.assert_called_once()


def test_hide_busy(source_module):
"""Test hiding busy indicator."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate hiding busy
piDSLM.hide_busy(app)

# Verify info was called
app.app.info.assert_called_once()


def test_upload_to_dropbox(source_module):
"""Test uploading to Dropbox."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate uploading to Dropbox
with patch('pidslm.subprocess') as mock_subprocess:
piDSLM.upload_to_dropbox(app)

# Verify subprocess was called
mock_subprocess.run.assert_called_once()


def test_get_image_files(source_module):
"""Test getting image files."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate getting image files
with patch('pidslm.glob') as mock_glob:
mock_glob.glob.return_value = ['/tmp/photo1.jpg', '/tmp/photo2.png']

images = piDSLM.get_image_files(app)

assert len(images) == 2
assert '/tmp/photo1.jpg' in images
assert '/tmp/photo2.png' in images


def test_create_directory(source_module):
"""Test creating directory."""
piDSLM = source_module.piDSLM

with patch.object(piDSLM, '__init__', lambda self: None):
app = piDSLM.__new__(piDSLM)
app.app = MagicMock()
app.camera_status = 'Ready'
app.current_image = ''

# Simulate creating directory
with patch('pidslm.os') as mock_os:
mock_os.path.exists.return_value = False

piDSLM.create_directory(app, '/tmp/test_dir')

# Verify makedirs was called
mock_os.makedirs.assert_called_once_with('/tmp/test_dir')


if __name__ == '__main__':
pytest.main([__file__, '-v'])