Sharfy commited on
Commit
8907dd8
Β·
1 Parent(s): 4f9da92

It be done

Browse files
Files changed (3) hide show
  1. bot.py +53 -85
  2. redis2sheets.py +28 -0
  3. sql2redis.py +4 -4
bot.py CHANGED
@@ -7,14 +7,14 @@ import os
7
  def generate_id(key):
8
  return r.incr(key)
9
 
10
- def generate_progress_bar(num_labels, width=20):
11
  print(num_labels)
12
- percentage = int(int(num_labels) / 300 * 100)
13
  completed_blocks = int(percentage * width / 100)
14
  remaining_blocks = width - completed_blocks
15
 
16
  progress_bar = 'β–“' * completed_blocks + 'β–‘' * remaining_blocks
17
- percentage_text = f' {num_labels}/50 identified 🦜🌱 '
18
 
19
  return f'πŸ† {progress_bar} {percentage_text}'
20
 
@@ -25,7 +25,7 @@ r = redis.from_url(redis_url)
25
 
26
  r.set('species_identified', 0)
27
 
28
- def improve_player_stats(ctx):
29
  # add 1 to the number of species identified
30
  value = r.get(b'species_identified').decode('utf-8')
31
  r.set(b'species_identified', int(value) + 1)
@@ -38,11 +38,14 @@ def improve_player_stats(ctx):
38
  if not r.exists(role_key):
39
  r.set(role_key, 'Naturalist')
40
 
41
- oc_key = f'{ctx.author.name}:occurances'.encode('utf-8')
42
- if not r.exists(oc_key):
43
- r.set(oc_key, 0)
 
44
  r.set(xp_key, int(r.get(xp_key)) + 10)
45
- r.set(oc_key, int(r.get(oc_key)) + 1)
 
 
46
 
47
  bot = discord.Bot()
48
 
@@ -103,7 +106,9 @@ async def image(ctx, id):
103
  embed = discord.Embed(color=discord.Colour.blurple())
104
  embed.set_author(name=f"Image Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
105
  embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
106
- # embed.add_field(name="Latest Label by", value=image_data['author'], inline=True)
 
 
107
  path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
108
  embed.set_image(url=path)
109
  await ctx.respond(embed=embed)
@@ -127,19 +132,21 @@ def get_conf_score(confidence: str):
127
  options=[
128
  Option(name="id", description="The ID of the image"),
129
  Option(name="label", description="The label for the image"),
130
- Option(name="confidence", description="Choose your confidence", autocomplete=confAutocomplete)
131
  ])
132
  async def label_image(ctx, id:int, label:str, confidence: str):
133
- label_cnt = generate_id(f'label:{id}')
134
- r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'label', label.encode('utf-8'))
135
- r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
 
 
 
136
  conf_score = get_conf_score(confidence)
137
- r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'confidence', conf_score)
138
 
139
  r.hset(f'image:{id}'.encode('utf-8'), b'label', label.encode('utf-8'))
140
  r.hset(f'image:{id}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
141
 
142
-
143
  # Fetch the image data from Redis
144
  image_data_bytes = r.hgetall(f'image:{id}'.encode('utf-8'))
145
  image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
@@ -149,13 +156,12 @@ async def label_image(ctx, id:int, label:str, confidence: str):
149
  embed = discord.Embed(color=discord.Colour.blurple())
150
  embed.set_author(name=f"Image Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
151
  embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
152
- embed.add_field(name="Label", value=image_data['label'], inline=True)
 
153
  embed.add_field(name="Proposed by", value=image_data['author'], inline=True)
154
  path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
155
  embed.set_image(url=path)
156
 
157
- improve_player_stats(ctx)
158
-
159
  await ctx.respond(f"{ctx.author.mention} labeled observation **{id}** as **{label}** πŸŽ‰ (Earned 10 XP)", embed=embed)
160
 
161
  @bot.command(description="Get progress bar.")
@@ -174,14 +180,12 @@ async def sound(ctx, id): # a slash command will be created with the name "ping"
174
  embed = discord.Embed(color=discord.Colour.blurple())
175
  embed.set_author(name=f"Sound Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
176
  embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
177
- embed.add_field(name="Label", value=sound_data['label'], inline=True)
 
178
  embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
179
- embed.add_field(name="Timestamp", value=sound_data['time'], inline=True)
180
 
181
- with open(sound_data['path'], 'rb') as f:
182
- sound = discord.File(f)
183
- message = await ctx.respond(file=sound, embed=embed)
184
- print('The ID of the message is:', message.id)
185
 
186
  @bot.command(
187
  description="Label sound observation",
@@ -189,77 +193,37 @@ async def sound(ctx, id): # a slash command will be created with the name "ping"
189
  Option(name="id", description="The ID of the sound"),
190
  Option(name="label", description="The label for the sound"),
191
  Option(name="timestamp", description="The timestamp of the observation"),
 
192
  ])
193
- async def label_sound(ctx, id:int, label:str, timestamp:str):
 
 
 
 
 
 
 
 
194
  r.hset(f'sound:{id}'.encode('utf-8'), b'label', label.encode('utf-8'))
195
- r.hset(f'sound:{id}'.encode('utf-8'), b'time', timestamp.encode('utf-8'))
196
  r.hset(f'sound:{id}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
197
 
198
  # Fetch the sound data from Redis
199
  sound_data_bytes = r.hgetall(f'sound:{id}'.encode('utf-8'))
200
  sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}
201
 
 
 
202
  # Create an embed
203
  embed = discord.Embed(color=discord.Colour.blurple())
204
  embed.set_author(name=f"Sound Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
205
  embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
206
- embed.add_field(name="Label", value=sound_data['label'], inline=True)
 
207
  embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
208
- embed.add_field(name="Time", value=sound_data['time'], inline=True)
209
 
210
- improve_player_stats(ctx)
211
-
212
- with open(sound_data['path'], 'rb') as f:
213
- sound = discord.File(f)
214
- await ctx.respond(f"{ctx.author.mention} labeled sound observation **{id}** as **{label}** at **{timestamp}** πŸŽ‰ (Earned 10 XP)", file=sound, embed=embed)
215
-
216
- @bot.command(
217
- description="List all unlabeled sound observations"
218
- )
219
- async def list_unlabeled_sound(ctx):
220
-
221
- unlabeled_ids = []
222
-
223
- # Fetch all the sound data from Redis
224
- keys = r.keys('sound:*'.encode('utf-8'))
225
- for key in keys:
226
- sound_data_bytes = r.hgetall(key)
227
- sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}
228
- if '❓' == sound_data['label']:
229
- unlabeled_ids = unlabeled_ids + [key.decode('utf-8')]
230
-
231
- # Create an embed
232
- embed = discord.Embed(color=discord.Colour.blurple())
233
- embed.set_author(name=f"Unlabeled Sound Observations", icon_url=ctx.author.display_avatar.url)
234
-
235
- for id in unlabeled_ids:
236
- embed.add_field(name=f"{id}", value="❓", inline=True)
237
-
238
- await ctx.respond(embed=embed)
239
-
240
- @bot.command(
241
- description="List all unlabeled image observations"
242
- )
243
- async def list_unlabeled_image(ctx):
244
-
245
- unlabeled_ids = []
246
-
247
- # Fetch all the image data from Redis
248
- keys = r.keys('image:*'.encode('utf-8'))
249
- for key in keys:
250
- image_data_bytes = r.hgetall(key)
251
- image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
252
- if '❓' == image_data['label']:
253
- unlabeled_ids = unlabeled_ids + [key.decode('utf-8')]
254
-
255
- # Create an embed
256
- embed = discord.Embed(color=discord.Colour.blurple())
257
- embed.set_author(name=f"Unlabeled Image Observations", icon_url=ctx.author.display_avatar.url)
258
-
259
- for id in unlabeled_ids:
260
- embed.add_field(name=f"{id}", value="❓", inline=True)
261
-
262
- await ctx.respond(embed=embed)
263
 
264
  @bot.command(
265
  description="Check your profile"
@@ -273,15 +237,19 @@ async def profile(ctx):
273
  if not r.exists(role_key):
274
  r.set(role_key, 'NATURALIST')
275
 
276
- oc_key = f'{ctx.author.name}:occurances'.encode('utf-8')
277
- if not r.exists(oc_key):
278
- r.set(oc_key, 0)
 
 
 
 
279
 
280
  # Create an embed
281
  embed = discord.Embed(color=discord.Colour.blurple())
282
  embed.set_author(name=f"{ctx.author.name} - Profile", icon_url=ctx.author.display_avatar.url)
283
  embed.add_field(name="**PROGRESS**", value=f"**Level**: 1\n**XP**: {r.get(xp_key).decode()}/1000\n", inline=False)
284
- embed.add_field(name="**STATS**", value=f"**🦜 Labels**: {r.get(oc_key).decode()}", inline=False)
285
  embed.set_thumbnail(url=ctx.author.display_avatar.url)
286
  embed.set_footer(text=f"πŸ† RANK: {r.get(role_key).decode()}")
287
  await ctx.respond(embed=embed)
 
7
  def generate_id(key):
8
  return r.incr(key)
9
 
10
+ def generate_progress_bar(num_labels, width=20, n=300):
11
  print(num_labels)
12
+ percentage = int(int(num_labels) / n * 100)
13
  completed_blocks = int(percentage * width / 100)
14
  remaining_blocks = width - completed_blocks
15
 
16
  progress_bar = 'β–“' * completed_blocks + 'β–‘' * remaining_blocks
17
+ percentage_text = f' {num_labels}/{n} identified 🦜🌱 '
18
 
19
  return f'πŸ† {progress_bar} {percentage_text}'
20
 
 
25
 
26
  r.set('species_identified', 0)
27
 
28
+ def improve_player_stats_image(ctx):
29
  # add 1 to the number of species identified
30
  value = r.get(b'species_identified').decode('utf-8')
31
  r.set(b'species_identified', int(value) + 1)
 
38
  if not r.exists(role_key):
39
  r.set(role_key, 'Naturalist')
40
 
41
+ img_oc_key = f'{ctx.author.name}:image'.encode('utf-8')
42
+ if not r.exists(img_oc_key):
43
+ r.set(img_oc_key, 0)
44
+
45
  r.set(xp_key, int(r.get(xp_key)) + 10)
46
+
47
+ r.set(img_oc_key, int(r.get(img_oc_key)) + 1)
48
+
49
 
50
  bot = discord.Bot()
51
 
 
106
  embed = discord.Embed(color=discord.Colour.blurple())
107
  embed.set_author(name=f"Image Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
108
  embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
109
+ embed.add_field(name="Recorded at", value=image_data['timestamp'], inline=True)
110
+ embed.add_field(name="Recent Label", value=image_data['label'], inline=True)
111
+ embed.add_field(name="Proposed by", value=image_data['author'], inline=True)
112
  path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
113
  embed.set_image(url=path)
114
  await ctx.respond(embed=embed)
 
132
  options=[
133
  Option(name="id", description="The ID of the image"),
134
  Option(name="label", description="The label for the image"),
135
+ Option(name="confidence", description="Choose your confidence: high, medium, low", autocomplete=confAutocomplete)
136
  ])
137
  async def label_image(ctx, id:int, label:str, confidence: str):
138
+
139
+ improve_player_stats_image(ctx)
140
+
141
+ label_cnt = generate_id(f'cnt:label:image:{id}')
142
+ r.hset(f'label:image:{id}:{label_cnt}'.encode('utf-8'), b'label', label.encode('utf-8'))
143
+ r.hset(f'label:image:{id}:{label_cnt}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
144
  conf_score = get_conf_score(confidence)
145
+ r.hset(f'label:image:{id}:{label_cnt}'.encode('utf-8'), b'confidence', conf_score)
146
 
147
  r.hset(f'image:{id}'.encode('utf-8'), b'label', label.encode('utf-8'))
148
  r.hset(f'image:{id}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
149
 
 
150
  # Fetch the image data from Redis
151
  image_data_bytes = r.hgetall(f'image:{id}'.encode('utf-8'))
152
  image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
 
156
  embed = discord.Embed(color=discord.Colour.blurple())
157
  embed.set_author(name=f"Image Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
158
  embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
159
+ embed.add_field(name="Recorded at", value=image_data['timestamp'], inline=True)
160
+ embed.add_field(name="Recent Label", value=image_data['label'], inline=True)
161
  embed.add_field(name="Proposed by", value=image_data['author'], inline=True)
162
  path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
163
  embed.set_image(url=path)
164
 
 
 
165
  await ctx.respond(f"{ctx.author.mention} labeled observation **{id}** as **{label}** πŸŽ‰ (Earned 10 XP)", embed=embed)
166
 
167
  @bot.command(description="Get progress bar.")
 
180
  embed = discord.Embed(color=discord.Colour.blurple())
181
  embed.set_author(name=f"Sound Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
182
  embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
183
+ embed.add_field(name="Recorded at", value=sound_data['timestamp'], inline=True)
184
+ embed.add_field(name="Recent Label", value=sound_data['label'], inline=True)
185
  embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
186
+ embed.add_field(name="Detected at Timestamp", value=sound_data['label_at'], inline=True)
187
 
188
+ await ctx.respond(f'Please listen to the sound here:\nhttps://gainforest.app/observations/{sound_data["uuid"]} 🦜🎡', embed=embed)
 
 
 
189
 
190
  @bot.command(
191
  description="Label sound observation",
 
193
  Option(name="id", description="The ID of the sound"),
194
  Option(name="label", description="The label for the sound"),
195
  Option(name="timestamp", description="The timestamp of the observation"),
196
+ Option(name="confidence", description="Choose your confidence: high, medium, low", autocomplete=confAutocomplete)
197
  ])
198
+ async def label_sound(ctx, id:int, label:str, timestamp:str, confidence: str):
199
+
200
+ sound_cnt = generate_id(f'cnt:label:sound:{id}')
201
+ r.hset(f'label:sound:{id}:{sound_cnt}'.encode('utf-8'), b'label', label.encode('utf-8'))
202
+ r.hset(f'label:sound:{id}:{sound_cnt}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
203
+ r.hset(f'label:sound:{id}:{sound_cnt}'.encode('utf-8'), b'label_at', timestamp.encode('utf-8'))
204
+ conf_score = get_conf_score(confidence)
205
+ r.hset(f'label:sound:{id}:{sound_cnt}'.encode('utf-8'), b'confidence', conf_score)
206
+
207
  r.hset(f'sound:{id}'.encode('utf-8'), b'label', label.encode('utf-8'))
208
+ r.hset(f'sound:{id}'.encode('utf-8'), b'label_at', timestamp.encode('utf-8'))
209
  r.hset(f'sound:{id}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
210
 
211
  # Fetch the sound data from Redis
212
  sound_data_bytes = r.hgetall(f'sound:{id}'.encode('utf-8'))
213
  sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}
214
 
215
+ print(sound_data)
216
+
217
  # Create an embed
218
  embed = discord.Embed(color=discord.Colour.blurple())
219
  embed.set_author(name=f"Sound Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
220
  embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
221
+ embed.add_field(name="Recorded at", value=sound_data['timestamp'], inline=True)
222
+ embed.add_field(name="Recent Label", value=sound_data['label'], inline=True)
223
  embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
224
+ embed.add_field(name="Detected at Timestamp", value=sound_data['label_at'], inline=True)
225
 
226
+ await ctx.respond(f'{ctx.author.mention} labeled sound observation **{id}** as **{label}** at **{timestamp}** πŸŽ‰ (Earned 10 XP).\nListen here:\nhttps://gainforest.app/observations/{sound_data["uuid"]} 🦜🎡', embed=embed)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
  @bot.command(
229
  description="Check your profile"
 
237
  if not r.exists(role_key):
238
  r.set(role_key, 'NATURALIST')
239
 
240
+ img_oc_key = f'{ctx.author.name}:image'.encode('utf-8')
241
+ if not r.exists(img_oc_key):
242
+ r.set(img_oc_key, 0)
243
+
244
+ s_oc_key = f'{ctx.author.name}:sound'.encode('utf-8')
245
+ if not r.exists(s_oc_key):
246
+ r.set(s_oc_key, 0)
247
 
248
  # Create an embed
249
  embed = discord.Embed(color=discord.Colour.blurple())
250
  embed.set_author(name=f"{ctx.author.name} - Profile", icon_url=ctx.author.display_avatar.url)
251
  embed.add_field(name="**PROGRESS**", value=f"**Level**: 1\n**XP**: {r.get(xp_key).decode()}/1000\n", inline=False)
252
+ embed.add_field(name="**STATS**", value=f"**🌱 Images labeled**: {r.get(img_oc_key).decode()}", inline=False)
253
  embed.set_thumbnail(url=ctx.author.display_avatar.url)
254
  embed.set_footer(text=f"πŸ† RANK: {r.get(role_key).decode()}")
255
  await ctx.respond(embed=embed)
redis2sheets.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import redis
2
+ import gspread
3
+
4
+ redis_url = 'redis://default:[email protected]:7369'
5
+ r = redis.from_url(redis_url)
6
+
7
+ gc = gspread.service_account()
8
+
9
+ # Open a sheet from a spreadsheet in one go
10
+ wks = gc.open("Labels").sheet1
11
+
12
+ rows = [['image id', 'label id', 'author', 'label', 'confidence (0 = low, 1 = medium, 2 = high)', 'image url', 'dashboard url', 'image preview']]
13
+
14
+ redis_keys = r.keys('label:image:*')
15
+ for i_key in redis_keys:
16
+ image_data_bytes = r.hgetall(i_key)
17
+ image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
18
+ image_id = i_key.decode().split(':')[-2]
19
+ raw_image_data_bytes = r.hgetall(f'image:{image_id}'.encode('utf-8'))
20
+ raw_image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in raw_image_data_bytes.items()}
21
+ path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{raw_image_data["awsCID"]}'
22
+ dashboard_url = f'https://gainforest.app/observations/{raw_image_data["uuid"]}'
23
+ row = [image_id, i_key.decode().split(':')[-1], image_data['author'], image_data['label'], image_data['confidence'], path, dashboard_url,'=IMAGE("{}", 2)'.format(path)]
24
+ rows.append(row)
25
+
26
+ # Update a range of cells using the top left corner address
27
+ wks.update('A1', rows, value_input_option='USER_ENTERED')
28
+ wks.format('A1:I1', {'textFormat': {'bold': True}})
sql2redis.py CHANGED
@@ -36,7 +36,7 @@ def get_all_images():
36
  # Fetch all the data returned by the database
37
  rows = cur.fetchall()
38
  for row in rows:
39
- image_cnt = generate_id('image_cnt')
40
  # Set multiple field-value pairs using HMSET
41
  fields_values = {
42
  'uuid': row[0],
@@ -65,7 +65,7 @@ def get_all_images():
65
 
66
  # Store labels and confidences in Redis using HMSET
67
  for label, confidence in zip(labels, confidences):
68
- pred_cnt = generate_id(f'prediction:{image_cnt}')
69
  fields_values = {
70
  'label': label,
71
  'confidence': confidence,
@@ -94,7 +94,7 @@ def get_all_sounds():
94
  # Fetch all the data returned by the database
95
  rows = cur.fetchall()
96
  for row in rows:
97
- sound_cnt = generate_id('sound_cnt')
98
  # Set multiple field-value pairs using HMSET
99
  fields_values = {
100
  'uuid': row[0],
@@ -122,4 +122,4 @@ def generate_id(key):
122
 
123
  r.flushdb()
124
  get_all_images()
125
- get_all_sounds()
 
36
  # Fetch all the data returned by the database
37
  rows = cur.fetchall()
38
  for row in rows:
39
+ image_cnt = generate_id('cnt:image')
40
  # Set multiple field-value pairs using HMSET
41
  fields_values = {
42
  'uuid': row[0],
 
65
 
66
  # Store labels and confidences in Redis using HMSET
67
  for label, confidence in zip(labels, confidences):
68
+ pred_cnt = generate_id(f'cnt:prediction:{image_cnt}')
69
  fields_values = {
70
  'label': label,
71
  'confidence': confidence,
 
94
  # Fetch all the data returned by the database
95
  rows = cur.fetchall()
96
  for row in rows:
97
+ sound_cnt = generate_id('cnt:sound')
98
  # Set multiple field-value pairs using HMSET
99
  fields_values = {
100
  'uuid': row[0],
 
122
 
123
  r.flushdb()
124
  get_all_images()
125
+ get_all_sounds()