def delete_keys(s3_bucket, key_list):

    """
    Deletes the specified list of keys from the specified bucket

    :param s3_bucket: The bucket from which to delete
    :param key_list: The list of keys to delete from the S3 bucket
    :return: A MultiDeleteResult object detailing the keys that were deleted and any errors encountered
    """

    delete = \
    {
        "Objects" :
        [
            { "Key": key }
            for key in key_list
        ]
    }

    if len(delete["Objects"]) > 0:

        response = s3_bucket.delete_objects(Delete = delete)

        return Struct(deleted = response.get("Deleted", []), errors = response.get("Errors", []))

    else:

        return Struct(deleted=[], errors=[])
Beispiel #2
0
 def test_drag_controller(self):
     """Make sure that we can drag photos around."""
     # Can we load files?
     data = Struct({'get_text': lambda: '\n'.join(DEMOFILES)})
     self.assertEqual(len(photos), 0)
     self.assertEqual(len(points), 0)
     gui.drag.photo_drag_end(None, None, 20, 20, data,
                             None, None, True)
     self.assertEqual(len(photos), 6)
     self.assertEqual(len(points), 374)
     for button in ('select_all', 'close', 'clear'):
         get_obj(button + '_button').emit('clicked')
     self.assertEqual(len(photos), 0)
     self.assertEqual(len(points), 0)
     
     gui.open_files(DEMOFILES)
     for photo in photos.values():
         # 'Drag' a ChamplainLabel and make sure the photo location matches.
         photo.label.set_location(random_coord(80), random_coord(180))
         photo.label.emit('drag-finish', Clutter.Event())
         self.assertEqual(photo.label.get_latitude(), photo.latitude)
         self.assertEqual(photo.label.get_longitude(), photo.longitude)
         self.assertGreater(len(photo.pretty_geoname()), 5)
         old = [photo.latitude, photo.longitude]
         
         # 'Drag' a photo onto the map and make sure that also works.
         selected.add(photo)
         data = Struct({'get_text': lambda: photo.filename})
         gui.drag.photo_drag_end(None, None, 20, 20, data,
                                 None, None, True)
         self.assertEqual(photo.label.get_latitude(), photo.latitude)
         self.assertEqual(photo.label.get_longitude(), photo.longitude)
         self.assertGreater(len(photo.pretty_geoname()), 5)
         self.assertNotEqual(photo.latitude, old[0])
         self.assertNotEqual(photo.longitude, old[1])
    def test_get_prefixed_keys_from_bucket_returns_keys():

        expected_bucket = "bucket"
        expected_prefix = "stacks"
        expected_key_list = \
        [
            Struct(name = "blah1", etag = "1halb"),
            Struct(name = "blah2", etag = "2halb"),
            Struct(name = "blah3", etag = "3halb")
        ]

        # define my own implementation of list
        def hijacked_list(**kwargs):
            assert kwargs["Bucket"] == expected_bucket
            assert kwargs["Prefix"] == expected_prefix
            return \
            {
                "Contents": [{ "Key": key.name, "ETag": key.etag } for key in expected_key_list]
            }

        s3 = get_s3_client()
        s3.list_objects_v2 = hijacked_list  # override Bucket's list function with my implementation

        # should call my list instead of the original
        keys = list(get_prefixed_keys_from_bucket(s3, expected_bucket, expected_prefix))

        assert keys == expected_key_list
Beispiel #4
0
    def test_string_functions(self):
        """Ensure that strings print properly."""
        environ['TZ'] = 'America/Edmonton'
        tzset()
        
        # Make a photo with a dummy ChamplainLabel.
        label = Struct()
        label.get_text = lambda: DEMOFILES[5]
        photo = Photograph(label.get_text(), lambda x: None)
        photo.read()
        photo.label = label
        
        photo.latitude  = None
        photo.longitude = None
        self.assertEqual(photo.pretty_coords(), 'Not geotagged')
        photo.latitude  = 10.0
        photo.longitude = 10.0
        self.assertEqual(photo.pretty_coords(), 'N 10.00000, E 10.00000')
        photo.latitude  = -10.0
        photo.longitude = -10.0
        self.assertEqual(photo.pretty_coords(), 'S 10.00000, W 10.00000')
        
        photo.timestamp = None
        self.assertIsNone(photo.pretty_time())
        photo.timestamp = 999999999
        self.assertEqual(photo.pretty_time(), '2001-09-08 07:46:39 PM')
        
        photo.altitude = None
        self.assertIsNone(photo.pretty_elevation())
        photo.altitude = -10.20005
        self.assertEqual(photo.pretty_elevation(), '10.2m below sea level')
        photo.altitude = 600.71
        self.assertEqual(photo.pretty_elevation(), '600.7m above sea level')
        
        self.assertEqual(photo.short_summary(),
"""2001-09-08 07:46:39 PM
S 10.00000, W 10.00000
600.7m above sea level""")
        self.assertEqual(photo.long_summary(),
"""<span size="larger">IMG_2411.JPG</span>
<span style="italic" size="smaller">2001-09-08 07:46:39 PM
S 10.00000, W 10.00000
600.7m above sea level</span>""")
        
        self.assertRegexpMatches(
            get_obj('maps_link').get_label(),
            r'href="http://maps.google.com'
        )
Beispiel #5
0
    def test_string_functions(self):
        """Ensure that strings print properly."""
        environ['TZ'] = 'America/Edmonton'
        tzset()
        
        # Make a photo with a dummy ChamplainLabel.
        label = Struct()
        label.get_text = lambda: DEMOFILES[5]
        photo = Photograph(label.get_text(), lambda x: None)
        photo.read()
        photo.label = label
        
        photo.latitude  = None
        photo.longitude = None
        self.assertEqual(photo.pretty_coords(), 'Not geotagged')
        photo.latitude  = 10.0
        photo.longitude = 10.0
        self.assertEqual(photo.pretty_coords(), 'N 10.00000, E 10.00000')
        photo.latitude  = -10.0
        photo.longitude = -10.0
        self.assertEqual(photo.pretty_coords(), 'S 10.00000, W 10.00000')
        
        photo.timestamp = None
        self.assertIsNone(photo.pretty_time())
        photo.timestamp = 999999999
        self.assertEqual(photo.pretty_time(), '2001-09-08 07:46:39 PM')
        
        photo.altitude = None
        self.assertIsNone(photo.pretty_elevation())
        photo.altitude = -10.20005
        self.assertEqual(photo.pretty_elevation(), '10.2m below sea level')
        photo.altitude = 600.71
        self.assertEqual(photo.pretty_elevation(), '600.7m above sea level')
        
        self.assertEqual(photo.short_summary(),
"""2001-09-08 07:46:39 PM
S 10.00000, W 10.00000
600.7m above sea level""")
        self.assertEqual(photo.long_summary(),
"""<span size="larger">IMG_2411.JPG</span>
<span style="italic" size="smaller">2001-09-08 07:46:39 PM
S 10.00000, W 10.00000
600.7m above sea level</span>""")
        
        self.assertRegexpMatches(
            get_obj('maps_link').get_label(),
            r'href="http://maps.google.com'
        )
def get_prefixed_keys_from_bucket(s3, bucket, s3_path):

    """
        Gets a list of keys from the S3 bucket in the specified path

        :param s3: An S3 client
        :param bucket: The S3 bucket to query
        :param s3_path: The path into the S3 bucket to query
        :return: A generator that lists keys from the S3 bucket in the specified path
    """

    kwargs = { "Bucket": bucket, "Prefix": s3_path }

    while True:

        response = s3.list_objects_v2(**kwargs)

        for key in response.get("Contents", []):

            yield Struct(name = key["Key"], etag = key["ETag"])

        try:

            kwargs["ContinuationToken"] = response["NextContinuationToken"]

        except KeyError:

            break
Beispiel #7
0
 def preferences_dialog(self, button, dialog, region, cities, colorpicker):
     """Allow the user to configure this application."""
     previous = Struct({
         'system': gst.get_boolean('system-timezone'),
         'lookup': gst.get_boolean('lookup-timezone'),
         'custom': gst.get_boolean('custom-timezone'),
         'region': region.get_active(),
         'city':   cities.get_active(),
         'color':  colorpicker.get_current_color()
     })
     if not dialog.run():
         colorpicker.set_current_color(previous.color)
         colorpicker.set_previous_color(previous.color)
         gst.set_boolean('system-timezone', previous.system)
         gst.set_boolean('lookup-timezone', previous.lookup)
         gst.set_boolean('custom-timezone', previous.custom)
         region.set_active(previous.region)
         cities.set_active(previous.city)
     dialog.hide()
 def my_new_key(key_name, etag):
     return Struct(name = key_name, etag = etag)
Beispiel #9
0
 def __format__(self):
     self.tag = Struct.string(4)
     self.rootnode_offset = Struct.uint32
     self.header_size = Struct.uint32
     self.data_offset = Struct.uint32
     self.zeroes = Struct.string(16)
Beispiel #10
0
    def __init__(self):
        self.progressbar = get_obj('progressbar')

        self.error = Struct({
            'message': get_obj('error_message'),
            'icon': get_obj('error_icon'),
            'bar': get_obj('error_bar')
        })

        self.error.bar.connect('response',
                               lambda widget, signal: widget.hide())

        self.strings = Struct({
            'quit':
            get_obj('quit').get_property('secondary-text'),
            'preview':
            get_obj('preview_label').get_text()
        })

        self.liststore = get_obj('loaded_photos')
        self.liststore.set_sort_column_id(TIMESTAMP, Gtk.SortType.ASCENDING)

        cell_string = Gtk.CellRendererText()
        cell_thumb = Gtk.CellRendererPixbuf()
        cell_thumb.set_property('stock-id', Gtk.STOCK_MISSING_IMAGE)
        cell_thumb.set_property('ypad', 6)
        cell_thumb.set_property('xpad', 12)

        column = Gtk.TreeViewColumn('Photos')
        column.pack_start(cell_thumb, False)
        column.add_attribute(cell_thumb, 'pixbuf', THUMB)
        column.pack_start(cell_string, False)
        column.add_attribute(cell_string, 'markup', SUMMARY)
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)

        get_obj('photos_view').append_column(column)

        self.drag = DragController(self.open_files)
        self.navigator = NavigationController()
        self.search = SearchController()
        self.prefs = PreferencesController()
        self.labels = LabelController()
        self.actors = ActorController()

        about = get_obj('about')
        about.set_version(REVISION)
        about.set_program_name(APPNAME)
        about.set_logo(
            GdkPixbuf.Pixbuf.new_from_file_at_size(
                join(PKG_DATA_DIR, PACKAGE + '.svg'), 192, 192))

        click_handlers = {
            'open_button': [self.add_files_dialog,
                            get_obj('open')],
            'save_button': [self.save_all_files],
            'clear_button': [clear_all_gpx],
            'close_button': [self.close_selected_photos],
            'revert_button': [self.revert_selected_photos],
            'about_button': [lambda b, d: d.run() and d.hide(), about],
            'apply_button': [self.apply_selected_photos, map_view],
            'select_all_button':
            [toggle_selected_photos, self.labels.selection]
        }
        for button, handler in click_handlers.items():
            get_obj(button).connect('clicked', *handler)

        accel = Gtk.AccelGroup()
        window = get_obj('main')
        window.resize(*gst.get('window-size'))
        window.connect('delete_event', self.confirm_quit_dialog)
        window.add_accel_group(accel)
        window.show_all()

        # Hide the unused button that appears beside the map source menu.
        get_obj('map_source_menu_button').get_child().get_children(
        )[0].set_visible(False)

        save_size = lambda v, s, size: gst.set_window_size(size())
        for prop in ['width', 'height']:
            map_view.connect('notify::' + prop, save_size, window.get_size)

        accel.connect(Gdk.keyval_from_name('q'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.confirm_quit_dialog)

        self.labels.selection.emit('changed')
        clear_all_gpx()

        metadata.delta = 0
        self.secbutton, self.minbutton = get_obj('seconds'), get_obj('minutes')
        for spinbutton in [self.secbutton, self.minbutton]:
            spinbutton.connect('value-changed', self.time_offset_changed)
        gst.bind('offset-minutes', self.minbutton, 'value')
        gst.bind('offset-seconds', self.secbutton, 'value')

        gst.bind('left-pane-page', get_obj('photo_camera_gps'), 'page')

        get_obj('open').connect('update-preview', self.update_preview,
                                get_obj('preview_label'),
                                get_obj('preview_image'))