From 5128d7967c2bcef32529b56f50196c02b2ba0c4b Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Wed, 3 Jun 2015 18:01:35 +0200 Subject: [PATCH 1/8] allow rendering random snapshot --- figureraspbian/db.py | 7 +++ figureraspbian/processus.py | 10 +++- figureraspbian/tests.py | 84 ++++++++++++++++++++++++++++++-- figureraspbian/ticketrenderer.py | 5 +- 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/figureraspbian/db.py b/figureraspbian/db.py index 10325b1..d4dc036 100644 --- a/figureraspbian/db.py +++ b/figureraspbian/db.py @@ -6,6 +6,7 @@ logger = logging.getLogger(__name__) import time import os +import random from ZEO import ClientStorage from ZODB import DB @@ -82,6 +83,9 @@ def get_code(self): def add_ticket(self, ticket): return self.data.add_ticket(ticket) + def get_random_ticket(self): + return self.data.get_random_ticket() + def upload_tickets(self): while self.data.last_upload_index != (len(self.data.tickets) - 1): try: @@ -110,6 +114,9 @@ def add_ticket(self, ticket): self.tickets.append(ticket) self._p_changed = True + def get_random_ticket(self): + return random.choice(self.tickets) if self.tickets else None + def upload_tickets(self): """ Upload the older ticket """ if len(self.tickets) > 0: diff --git a/figureraspbian/processus.py b/figureraspbian/processus.py index 865ae85..56728f1 100644 --- a/figureraspbian/processus.py +++ b/figureraspbian/processus.py @@ -13,6 +13,8 @@ from .db import Database, managed import phantomjs +# Pre-calculated random_ticket to be used +random_snapshot_path = None def run(): with managed(Database()) as db: @@ -51,9 +53,11 @@ def run(): random_image_selections = [ticketrenderer.random_selection(variable) for variable in ticket_template['image_variables']] + rendered_html = ticketrenderer.render( ticket_template['html'], snapshot_path, + random_snapshot_path, code, date, ticket_template['images'], @@ -81,7 +85,6 @@ def run(): # Set Output to True devices.OUTPUT.set(False) - # Save ticket to disk ticket_path = join(settings.MEDIA_ROOT, 'tickets', basename(snapshot_path)) with open(ticket_path, "wb") as f: @@ -93,6 +96,11 @@ def run(): if settings.BACKUP_ON: shutil.copy2(snapshot_path, "/mnt/%s" % basename(snapshot_path)) + # Calculate random snapshot path + global random_snapshot_path + random_ticket = db.get_random_ticket() + random_snapshot_path = random_ticket['snapshot'] if random_ticket else None + # add task upload ticket task to the queue ticket = { 'installation': installation.id, diff --git a/figureraspbian/tests.py b/figureraspbian/tests.py index 9c91513..4dad750 100644 --- a/figureraspbian/tests.py +++ b/figureraspbian/tests.py @@ -16,7 +16,6 @@ import transaction from .db import transaction_decorate -from . import phantomjs class TestTicketRenderer(unittest.TestCase): @@ -41,9 +40,10 @@ def test_random_selection_empty_variable(self): def test_render(self): """ - TicketRenderer should render a ticket + TicketRenderer should render a ticket when no random_snapshot """ - html = '{{snapshot}} {{code}} {{datetime | datetimeformat}} {{textvariable_1}} {{imagevariable_2}} {{image_1}}' + html = '{{snapshot}} {{code}} {{datetime | datetimeformat}} ' \ + '{{textvariable_1}} {{imagevariable_2}} {{image_1}}' code = '5KIJ7' date = parser.parse("Tue Jun 22 07:46:22 EST 2010") images = [{'id': '1', 'image': 'path/to/image'}] @@ -52,6 +52,7 @@ def test_render(self): rendered_html = ticketrenderer.render( html, '/path/to/snapshot', + None, code, date, images, @@ -61,6 +62,51 @@ def test_render(self): 'http://localhost:8080/media/images/image http://localhost:8080/media/images/image' self.assertIn(expected, rendered_html) + def test_render_random_snapshot_None(self): + """ + TicketRender should render a ticket when random snapshot but None is provided + """ + html = '' + code = '5KIJ7' + date = parser.parse("Tue Jun 22 07:46:22 EST 2010") + images = [{'id': '1', 'image': 'path/to/image'}] + random_text_selections = [('1', {'id': '2', 'text': 'Titi'}), ('2', None)] + random_image_slections = [('2', {'id': 1, 'image': '/path/to/image'})] + rendered_html = ticketrenderer.render( + html, + '/path/to/snapshot', + None, + code, + date, + images, + random_text_selections, + random_image_slections) + expected = '' + self.assertIn(expected, rendered_html) + + def test_render_random_snapshot(self): + """ + TicketRenderer should render a ticket with a random snapshot + """ + html = '' + code = '5KIJ7' + date = parser.parse("Tue Jun 22 07:46:22 EST 2010") + images = [{'id': '1', 'image': 'path/to/image'}] + random_text_selections = [('1', {'id': '2', 'text': 'Titi'}), ('2', None)] + random_image_slections = [('2', {'id': 1, 'image': '/path/to/image'})] + rendered_html = ticketrenderer.render( + html, + '/path/to/snapshot', + '/path/to/random/snapshot', + code, + date, + images, + random_text_selections, + random_image_slections) + expected = '' + self.assertIn(expected, rendered_html) + + def test_set_date_format(self): """ Ticket renderer should handle datetimeformat filter @@ -408,6 +454,38 @@ def test_upload_tickets(self): db.upload_tickets() self.assertFalse(api.create_ticket.called) + def test_get_random_ticket(self): + """ + Get a random ticket should pick a random ticket in the ticket list + """ + with managed(Database()) as db: + time1 = datetime.now(pytz.timezone(settings.TIMEZONE)) + time2 = datetime.now(pytz.timezone(settings.TIMEZONE)) + ticket = db.get_random_ticket() + self.assertIsNone(ticket) + ticket_1 = { + 'installation': '1', + 'snapshot': '/path/to/snapshot', + 'ticket': 'path/to/ticket', + 'dt': time1, + 'code': 'JHUYG', + 'random_text_selections': [], + 'random_image_selections': [] + } + ticket_2 = { + 'installation': '1', + 'snapshot': '/path/to/snapshot', + 'ticket': 'path/to/ticket', + 'dt': time2, + 'code': 'JU76G', + 'random_text_selections': [], + 'random_image_selections': [] + } + db.add_ticket(ticket_1) + db.add_ticket(ticket_2) + ticket = db.get_random_ticket() + self.assertIn(ticket, [ticket_1, ticket_2]) + class TestProcessus(unittest.TestCase): diff --git a/figureraspbian/ticketrenderer.py b/figureraspbian/ticketrenderer.py index 2846aa6..9948162 100644 --- a/figureraspbian/ticketrenderer.py +++ b/figureraspbian/ticketrenderer.py @@ -48,9 +48,12 @@ def random_selection(variable): return variable['id'], random.choice(variable['items']) -def render(html, snapshot, code, date, images, random_text_selections, random_image_selections): +def render(html, snapshot, random_snapshot, code, date, images, random_text_selections, random_image_selections): snapshot_url = 'http://localhost:8080/media/snapshots/%s' % os.path.basename(snapshot) context = {'snapshot': snapshot_url} + if random_snapshot: + random_snapshot_url = 'http://localhost:8080/media/snapshots/%s' % os.path.basename(random_snapshot) + context = {'random_snapshot': random_snapshot_url} for (text_variable_id, item) in random_text_selections: text = item['text'] if item else '' context['textvariable_%s' % text_variable_id] = text From 04b64ac9e55943418bb2e185c8255a595705f229 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Wed, 3 Jun 2015 19:52:44 +0200 Subject: [PATCH 2/8] get code at the end of the processus --- figureraspbian/processus.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/figureraspbian/processus.py b/figureraspbian/processus.py index 56728f1..b18c295 100644 --- a/figureraspbian/processus.py +++ b/figureraspbian/processus.py @@ -15,6 +15,7 @@ # Pre-calculated random_ticket to be used random_snapshot_path = None +code = None def run(): with managed(Database()) as db: @@ -41,10 +42,6 @@ def run(): blinking_task = devices.OUTPUT.blink() # Render ticket - start = time.time() - code = db.get_code() - end = time.time() - logger.info('Successfully claimed code in %s seconds', end - start) start = time.time() random_text_selections = [ticketrenderer.random_selection(variable) for @@ -54,11 +51,20 @@ def run(): variable in ticket_template['image_variables']] + if code: + current_code = code + else: + # we need to claim a code + start = time.time() + current_code = db.get_code() + end = time.time() + logger.info('Successfully claimed code in %s seconds', end - start) + rendered_html = ticketrenderer.render( ticket_template['html'], snapshot_path, random_snapshot_path, - code, + current_code, date, ticket_template['images'], random_text_selections, @@ -101,6 +107,13 @@ def run(): random_ticket = db.get_random_ticket() random_snapshot_path = random_ticket['snapshot'] if random_ticket else None + # Calculate new code + start = time.time() + global code + code = db.get_code() + end = time.time() + logger.info('Successfully claimed code in %s seconds', end - start) + # add task upload ticket task to the queue ticket = { 'installation': installation.id, From 448a6bdd28449f3c992daca0b4ed6d8542d7bf65 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 09:38:07 +0200 Subject: [PATCH 3/8] fix SyntaxError --- figureraspbian/processus.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/figureraspbian/processus.py b/figureraspbian/processus.py index b18c295..95d1c45 100644 --- a/figureraspbian/processus.py +++ b/figureraspbian/processus.py @@ -17,11 +17,11 @@ random_snapshot_path = None code = None + def run(): with managed(Database()) as db: try: installation = db.data.installation - if installation.id is not None: # Database is initialized ! @@ -51,6 +51,7 @@ def run(): variable in ticket_template['image_variables']] + global code if code: current_code = code else: @@ -60,10 +61,17 @@ def run(): end = time.time() logger.info('Successfully claimed code in %s seconds', end - start) + global random_snapshot_path + if random_snapshot_path: + current_random_snapshot_path = random_snapshot_path + else: + random_ticket = db.get_random_ticket() + current_random_snapshot_path = random_ticket['snapshot'] if random_ticket else None + rendered_html = ticketrenderer.render( ticket_template['html'], snapshot_path, - random_snapshot_path, + current_random_snapshot_path, current_code, date, ticket_template['images'], @@ -103,13 +111,11 @@ def run(): shutil.copy2(snapshot_path, "/mnt/%s" % basename(snapshot_path)) # Calculate random snapshot path - global random_snapshot_path random_ticket = db.get_random_ticket() random_snapshot_path = random_ticket['snapshot'] if random_ticket else None # Calculate new code start = time.time() - global code code = db.get_code() end = time.time() logger.info('Successfully claimed code in %s seconds', end - start) From a3223fa56c433467d3e8814803ff8d814d2f2db3 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 09:51:26 +0200 Subject: [PATCH 4/8] fix snapshot not rendered --- figureraspbian/ticketrenderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/figureraspbian/ticketrenderer.py b/figureraspbian/ticketrenderer.py index 9948162..57f55c3 100644 --- a/figureraspbian/ticketrenderer.py +++ b/figureraspbian/ticketrenderer.py @@ -53,7 +53,7 @@ def render(html, snapshot, random_snapshot, code, date, images, random_text_sele context = {'snapshot': snapshot_url} if random_snapshot: random_snapshot_url = 'http://localhost:8080/media/snapshots/%s' % os.path.basename(random_snapshot) - context = {'random_snapshot': random_snapshot_url} + context['random_snapshot'] = random_snapshot_url for (text_variable_id, item) in random_text_selections: text = item['text'] if item else '' context['textvariable_%s' % text_variable_id] = text From 6783349f680c8cff1faad710baae3eb7cb59ad70 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 10:04:37 +0200 Subject: [PATCH 5/8] fix wrong code printer --- figureraspbian/processus.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/figureraspbian/processus.py b/figureraspbian/processus.py index 95d1c45..4ab850f 100644 --- a/figureraspbian/processus.py +++ b/figureraspbian/processus.py @@ -110,16 +110,6 @@ def run(): if settings.BACKUP_ON: shutil.copy2(snapshot_path, "/mnt/%s" % basename(snapshot_path)) - # Calculate random snapshot path - random_ticket = db.get_random_ticket() - random_snapshot_path = random_ticket['snapshot'] if random_ticket else None - - # Calculate new code - start = time.time() - code = db.get_code() - end = time.time() - logger.info('Successfully claimed code in %s seconds', end - start) - # add task upload ticket task to the queue ticket = { 'installation': installation.id, @@ -131,6 +121,17 @@ def run(): 'random_image_selections': random_image_selections } db.add_ticket(ticket) + + # Calculate random snapshot path + random_ticket = db.get_random_ticket() + random_snapshot_path = random_ticket['snapshot'] if random_ticket else None + + # Calculate new code + start = time.time() + code = db.get_code() + end = time.time() + logger.info('Successfully claimed code in %s seconds', end - start) + else: logger.warning("Current installation has ended. Skipping processus execution") except Exception as e: From c401aa01a407335934efbbeed415a3869cb678c1 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 10:09:42 +0200 Subject: [PATCH 6/8] always get date from Raspberry Pi --- figureraspbian/devices/camera.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/figureraspbian/devices/camera.py b/figureraspbian/devices/camera.py index 9a9dc80..b71a69f 100644 --- a/figureraspbian/devices/camera.py +++ b/figureraspbian/devices/camera.py @@ -55,18 +55,7 @@ def capture(self, installation): if settings.FLASH_ON: self.light.flash_off() - # Get date - if settings.CAMERA_TYPE == 'CANON': - date = datetime.now(pytz.timezone(settings.TIMEZONE)) - else: - error, info = gp.gp_camera_file_get_info( - self.camera, - folder, - name, - self.context) - date = datetime.fromtimestamp(info.file.mtime) - timezone = pytz.timezone(settings.TIMEZONE) - timezone.localize(date) + date = datetime.now(pytz.timezone(settings.TIMEZONE)) # Get snapshot file error, camera_file = gp.gp_camera_file_get( From 9f9778ff57e1d4f1f2e5e65b7aeb9493d0eba007 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 10:25:04 +0200 Subject: [PATCH 7/8] we should pick random snapshot only in current installation --- figureraspbian/db.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/figureraspbian/db.py b/figureraspbian/db.py index d4dc036..dae4f69 100644 --- a/figureraspbian/db.py +++ b/figureraspbian/db.py @@ -115,7 +115,8 @@ def add_ticket(self, ticket): self._p_changed = True def get_random_ticket(self): - return random.choice(self.tickets) if self.tickets else None + active_tickets = [ticket for ticket in self.tickets if ticket['installation'] == self.installation.id] + return random.choice(active_tickets) if active_tickets else None def upload_tickets(self): """ Upload the older ticket """ From b92c81462fedfa7aec2f4e0fdaedad813906bc63 Mon Sep 17 00:00:00 2001 From: benoitguigal Date: Thu, 4 Jun 2015 10:56:03 +0200 Subject: [PATCH 8/8] set panpan as random snapshot when first ticket of installation is printed --- figureraspbian/__main__.py | 8 +++++++- figureraspbian/ticketrenderer.py | 7 ++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/figureraspbian/__main__.py b/figureraspbian/__main__.py index 8a9b362..aa4d426 100644 --- a/figureraspbian/__main__.py +++ b/figureraspbian/__main__.py @@ -1,5 +1,5 @@ # -*- coding: utf8 -*- - +import os import time import logging logging.basicConfig(level='INFO') @@ -46,6 +46,12 @@ def get_listener(): api.download(ticket_css_url, settings.STATIC_ROOT) except Exception: pass + logger.info("Downloading example snapshot...") + snapshot_example_url = "%s/%s" % (settings.API_HOST, 'static/snapshots/example.jpg') + try: + api.download(snapshot_example_url, os.path.join(settings.MEDIA_ROOT, 'snapshots')) + except Exception: + pass listener = get_listener() diff --git a/figureraspbian/ticketrenderer.py b/figureraspbian/ticketrenderer.py index 57f55c3..f2abd72 100644 --- a/figureraspbian/ticketrenderer.py +++ b/figureraspbian/ticketrenderer.py @@ -51,9 +51,10 @@ def random_selection(variable): def render(html, snapshot, random_snapshot, code, date, images, random_text_selections, random_image_selections): snapshot_url = 'http://localhost:8080/media/snapshots/%s' % os.path.basename(snapshot) context = {'snapshot': snapshot_url} - if random_snapshot: - random_snapshot_url = 'http://localhost:8080/media/snapshots/%s' % os.path.basename(random_snapshot) - context['random_snapshot'] = random_snapshot_url + random_snapshot_url = ('http://localhost:8080/media/snapshots/%s' % os.path.basename(random_snapshot) if + random_snapshot else + 'http://localhost:8080/media/snapshots/example.jpg') + context['random_snapshot'] = random_snapshot_url for (text_variable_id, item) in random_text_selections: text = item['text'] if item else '' context['textvariable_%s' % text_variable_id] = text