(action, poll_id=None)
return ret
If action is 'list', get metadata for all saved TAXII polls. If action
    is 'delete' and a Poll ID is provided, delete all content
    related to that poll before returning the remaining poll metadata.

    :param action: If 'list', return metadata.
                   If 'download', return XML-formatted data
                   If 'delete', delete a set of data, then return metadata
    :type action: string
    :param poll_id: ID of the poll for which content should be deleted
    :type poll_id: string
    :returns: dict with keys:
              "unimported" (dict) - Polls that have not yet been imported
              "errored" (dict) - Polls that errored during import
              "success" (bool) - True if poll data was successfully retrieved
              "msg" (string) - If success is False, provide an error msg
If action is 'list', get metadata for all saved TAXII polls. If action
    is 'delete' and a Poll ID is provided, delete all content
    related to that poll before returning the remaining poll metadata.
If action is list get metadata for all saved TAXII polls . If action is delete and a Poll ID is provided delete all content related to that poll before returning the remaining poll metadata .
def get_saved_polls(action, poll_id=None):
    """
    If action is 'list', get metadata for all saved TAXII polls. If action
    is 'delete' and a Poll ID is provided, delete all content
    related to that poll before returning the remaining poll metadata.

    :param action: If 'list', return metadata.
                   If 'download', return XML-formatted data
                   If 'delete', delete a set of data, then return metadata
    :type action: string
    :param poll_id: ID of the poll for which content should be deleted
    :type poll_id: string
    :returns: dict with keys:
              "unimported" (dict) - Polls that have not yet been imported
              "errored" (dict) - Polls that errored during import
              "success" (bool) - True if poll data was successfully retrieved
              "msg" (string) - If success is False, provide an error msg
    """
    if action in ('delete', 'download'):
        p_time = datetime.utcfromtimestamp(float(poll_id))
        data = taxii.TaxiiContent.objects(poll_time=p_time) # get data from dB
        if action == 'delete':
            data.delete() # delete the given poll
            return {'success': True}
        else: # download
            if  data[0].timerange == 'STIX File Upload':
                filename = data[0].feed
                res = ''.join(block.content for block in data)
                return {'response': res, 'filename': filename}

            # rebuild XML
            filename = "taxii_poll-%s.xml" % p_time.strftime('%Y%m%dT%H%M%S')
            content_blocks = []
            for block in data:
                stamp = datetime.strptime(block.block_label, '%Y-%m-%d %H:%M:%S')
                stamp = stamp.replace(tzinfo=pytz.utc)
                c_block = tm11.ContentBlock(content_binding = t.CB_STIX_XML_111,
                                            timestamp_label = stamp,
                                            content = block.content)
                content_blocks.append(c_block)
            res = tm11.PollResponse(message_id=block.taxii_msg_id,
                                    in_response_to="Unknown",
                                    collection_name=block.feed,
                                    message=block.timerange,
                                    content_blocks=content_blocks)
            return {'response': res.to_xml(), 'filename': filename}
    elif action != 'list':
        return {'success': False, 'msg': 'Invalid action type'}

    content = taxii.TaxiiContent.objects()
    polls = {}
    ret = {'unimported': [], 'errored': []}
    for block in content:
        time = str(block.poll_time)
        poll_id = '%.3f' % (block.poll_time-datetime(1970,1,1)).total_seconds()
        if time not in polls:
            polls[time] = {'time': time,
                           'poll_id': poll_id,
                           'msg_id': block.taxii_msg_id,
                           'source': block.hostname,
                           'feed': block.feed,
                           'timerange': block.timerange,
                           'analyst': block.analyst,
                           'count': 1,
                           'errors': block.errors,
                           'import_failed': block.import_failed}
        else:
            polls[time]['count'] += 1
            polls[time]['errors'].extend(block.errors)
            if block.import_failed:
                polls[time]['import_failed'] = True

    for poll in polls:
        if polls[poll]['import_failed']:
            ret['errored'].append(polls[poll])
        else:
            ret['unimported'].append(polls[poll])

    # sort the lists chronologically
    ret['unimported'].sort(key=lambda k: k['time'])
    ret['errored'].sort(key=lambda k: k['time'])

    ret['success'] = True
    return ret
def get_saved_polls ( action , poll_id = None ) : if action in ( 'delete' , 'download' ) : p_time = datetime . utcfromtimestamp ( float ( poll_id ) ) data = taxii . TaxiiContent . objects ( poll_time = p_time ) # get data from dB if action == 'delete' : data . delete ( ) # delete the given poll return { 'success' : True } else : # download if data [ 0 ] . timerange == 'STIX File Upload' : filename = data [ 0 ] . feed res = '' . join ( block . content for block in data ) return { 'response' : res , 'filename' : filename } # rebuild XML filename = "taxii_poll-%s.xml" % p_time . strftime ( '%Y%m%dT%H%M%S' ) content_blocks = [ ] for block in data : stamp = datetime . strptime ( block . block_label , '%Y-%m-%d %H:%M:%S' ) stamp = stamp . replace ( tzinfo = pytz . utc ) c_block = tm11 . ContentBlock ( content_binding = t . CB_STIX_XML_111 , timestamp_label = stamp , content = block . content ) content_blocks . append ( c_block ) res = tm11 . PollResponse ( message_id = block . taxii_msg_id , in_response_to = "Unknown" , collection_name = block . feed , message = block . timerange , content_blocks = content_blocks ) return { 'response' : res . to_xml ( ) , 'filename' : filename } elif action != 'list' : return { 'success' : False , 'msg' : 'Invalid action type' } content = taxii . TaxiiContent . objects ( ) polls = { } ret = { 'unimported' : [ ] , 'errored' : [ ] } for block in content : time = str ( block . poll_time ) poll_id = '%.3f' % ( block . poll_time - datetime ( 1970 , 1 , 1 ) ) . total_seconds ( ) if time not in polls : polls [ time ] = { 'time' : time , 'poll_id' : poll_id , 'msg_id' : block . taxii_msg_id , 'source' : block . hostname , 'feed' : block . feed , 'timerange' : block . timerange , 'analyst' : block . analyst , 'count' : 1 , 'errors' : block . errors , 'import_failed' : block . import_failed } else : polls [ time ] [ 'count' ] += 1 polls [ time ] [ 'errors' ] . extend ( block . errors ) if block . import_failed : polls [ time ] [ 'import_failed' ] = True for poll in polls : if polls [ poll ] [ 'import_failed' ] : ret [ 'errored' ] . append ( polls [ poll ] ) else : ret [ 'unimported' ] . append ( polls [ poll ] ) # sort the lists chronologically ret [ 'unimported' ] . sort ( key = lambda k : k [ 'time' ] ) ret [ 'errored' ] . sort ( key = lambda k : k [ 'time' ] ) ret [ 'success' ] = True return ret