· 5 years ago · Aug 20, 2020, 12:38 PM
1import json
2import logging
3import os
4import boto3
5from botocore.vendored import requests
6from urllib.parse import unquote_plus
7
8logger = logging.getLogger()
9logger.setLevel(logging.INFO)
10
11# get environment variables
12ff_api_host = os.environ['ff_api_host']
13rd_api_host = os.environ['rd_api_host']
14login_username = os.environ['rd2020_username']
15login_password = os.environ['rd2020_password']
16aws_access_key_id = os.environ['aws_access_key_id']
17aws_secret_access_key = os.environ['aws_secret_key']
18region = os.environ['aws_region']
19
20# TODO: the server should detect media format, not from the lambda function
21video_formats = ['avi', 'mp4', 'flv', 'wmv', 'mov', 'mkv']
22image_formats = ['jpg', 'png', 'jpeg', 'gif']
23
24s3 = boto3.client('s3',
25 aws_access_key_id=aws_access_key_id,
26 aws_secret_access_key=aws_secret_access_key,
27 region_name=region
28)
29
30def lambda_handler(event, context):
31 for record in event['Records']:
32 bucket = record['s3']['bucket']['name']
33 key = unquote_plus(record['s3']['object']['key'])
34 keyInLowerCase = key.lower()
35 isMedia = False
36
37 logger.info(f'[record]: {record}')
38 logger.info(f'[bucket]:{bucket}')
39 logger.info(f'[key]:{key}')
40
41 for video_format in video_formats:
42 if (keyInLowerCase.endswith(video_format)):
43 logger.info('===> video file detected')
44 response = requests.get(f'{ff_api_host}/detect_from_video?bucket={bucket}&key={key}')
45 logger.info(f'===> request response {response.text}')
46 isMedia = True
47 break
48
49 if not isMedia:
50 for image_format in image_formats:
51 if (keyInLowerCase.endswith(image_format)):
52 logger.info("===> image file detected")
53
54 response = requests.get(f'{ff_api_host}/sync/detect_from_image?bucket={bucket}&key={key}')
55 logger.info(f'===> request response {response.text}')
56 isMedia = True
57 break
58
59 if keyInLowerCase.endswith('.json'):
60 logger.info('===> json file detected')
61 # parse json to retrieve prediction values, id, and other info
62 media_details = parse_json_file(bucket, key)
63 token = get_jwt_token()
64 logger.info('===> token retrieved from api')
65 update_media_database(token, media_details)
66 logger.info('===> updated media database with latest prediction')
67
68 isMedia = True
69 break
70
71 if not isMedia:
72 logger.info("===> unable to detect media format by the file extention")
73
74 return {
75 'statusCode': 200
76 }
77
78def parse_json_file(bucket, key):
79 file_location = f'/tmp/{key}'
80 logger.info(f'bucket: {bucket}, key: {key}')
81 logger.info('===> downloading json file from s3')
82 s3.download_file(bucket, key, file_location)
83 with open(file_location, 'r') as media_json:
84 media_details = json.load(media_json)
85
86 return media_details
87
88def get_jwt_token():
89 data = {
90 'username': login_username,
91 'password': login_password
92 }
93 try:
94 response = requests.post(f'{rd_api_host}/auth/login', data)
95 response.raise_for_status()
96 return response.json()['token']
97 except Exception as e:
98 raise Exception(str(e))
99
100
101def update_media_database(token, media_details):
102 predictionNumber = float(media_details['prediction'])
103 mediaId = media_details['mediaId']
104 headers = {
105 'Authorization': f'Bearer {token}'
106 }
107
108 if predictionNumber > 0.5:
109 status = 'FAKE'
110 elif predictionNumber <= 0.5 and predictionNumber >= 0:
111 status = 'AUTHENTIC'
112 else:
113 status = 'NEEDS_MANUAL'
114
115 data = {
116 'predictionNumber': predictionNumber,
117 'status': status
118 }
119
120 if 'heatmap_url' in media_details.keys():
121 data['heatmapLocation'] = media_details['heatmap_url']
122
123 try:
124 response = requests.put(f'{rd_api_host}/media/{mediaId}', data=data, headers=headers)
125 response.raise_for_status()
126 except Exception as e:
127 raise Exception(str(e))