File size: 11,466 Bytes
0424b36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
import discord
from discord import Option
import redis
import os

# Function to generate auto-incremented IDs
def generate_id(key):
    return r.incr(key)

def generate_progress_bar(num_labels, width=20):
    print(num_labels)
    percentage = int(int(num_labels) / 300 * 100)
    completed_blocks = int(percentage * width / 100)
    remaining_blocks = width - completed_blocks

    progress_bar = 'β–“' * completed_blocks + 'β–‘' * remaining_blocks
    percentage_text = f' {num_labels}/50 identified 🦜🌱 '

    return f'πŸ† {progress_bar} {percentage_text}'

# Redis client setup

redis_url = 'redis://default:[email protected]:7369'
r = redis.from_url(redis_url)

r.set('species_identified', 0)

def improve_player_stats(ctx):
    # add 1 to the number of species identified
    value = r.get(b'species_identified').decode('utf-8')
    r.set(b'species_identified', int(value) + 1)

    xp_key = f'{ctx.author.name}:XP'.encode('utf-8')
    if not r.exists(xp_key):
        r.set(xp_key, 0)

    role_key = f'{ctx.author.name}:role'.encode('utf-8')
    if not r.exists(role_key):
        r.set(role_key, 'Naturalist')

    oc_key = f'{ctx.author.name}:occurances'.encode('utf-8')
    if not r.exists(oc_key):
        r.set(oc_key, 0)
    r.set(xp_key, int(r.get(xp_key)) + 10)
    r.set(oc_key, int(r.get(oc_key)) + 1)

bot = discord.Bot()

@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")

@bot.command(
            description="Get image predictions", 
            options=[
                Option(name="id", description="The ID of the image")
            ])
async def predict_image(ctx, id):
    # Fetch the image data from Redis
    image_data_bytes = r.hgetall(f'image:{id}'.encode('utf-8'))
    image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
    path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
    print(image_data)
    message = f"**Image Observation: {id} by _{image_data['sensor']}_**"

    message += "\n_Below are Top 10 predictions of AI_"
    emoji_unicode_list = [chr(0x30 + i) + '\uFE0F\u20E3' for i in range(11)]

    prediction_data_bytes = r.hgetall(f'prediction:{id}:1'.encode('utf-8'))
    prediction_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in prediction_data_bytes.items()}

    embed = discord.Embed(
        title="",
        description=f"Label: {prediction_data['label']}\nPredictions of our AI algorithms",
        color=discord.Colour.blurple(), # Pycord provides a class with default colors you can choose from
    )
    embed.set_author(name=f"Image Observation {id} - AI Predictions", icon_url=ctx.author.display_avatar.url)

    for i in range(1, 10):
        prediction_data_bytes = r.hgetall(f'prediction:{id}:{i}'.encode('utf-8'))
        prediction_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in prediction_data_bytes.items()}
        species = prediction_data['label']
        score = prediction_data['confidence']
        # message = message + f'\n> {emoji_unicode_list[i-1]} {species} with confidence {score}'
        embed.add_field(name=f'{species}', value=f'Confidence: {float(score):.4f}', inline=True)
    embed.set_thumbnail(url=path)

    # Send the image
    await ctx.respond("Hint: You can use [NParks Flora & Fauna Database](https://www.nparks.gov.sg/florafaunaweb) to verify", embed=embed)

@bot.command(
            description="Get image observation", 
            options=[
                Option(name="id", description="The ID of the image")
            ])
async def image(ctx, id):
    # Fetch the image data from Redis
    image_data_bytes = r.hgetall(f'image:{id}'.encode('utf-8'))
    image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
    print(image_data)

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Image Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
    embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
    # embed.add_field(name="Latest Label by", value=image_data['author'], inline=True)
    path = f'https://gainforest-transparency-dashboard.s3.amazonaws.com/{image_data["awsCID"]}'
    embed.set_image(url=path)
    await ctx.respond(embed=embed)

@bot.command(
        description="Label image observation",
        options=[
            Option(name="id", description="The ID of the image"),
            Option(name="label", description="The label for the image"),
            Option(name="confidence", description="The confidence for the label"),
    ])
async def label_image(ctx, id:int, label:str, confidence:int):
    label_cnt = generate_id(f'label:{id}')
    r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'label', label.encode('utf-8'))
    r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))
    r.hset(f'label:{id}:{label_cnt}'.encode('utf-8'), b'confidence', ctx.author.mention.encode('utf-8'))

    # Fetch the image data from Redis
    image_data_bytes = r.hgetall(f'image:{id}'.encode('utf-8'))
    image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
    print(image_data)

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Image Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
    embed.add_field(name="Sensor", value=image_data['sensor'], inline=True)
    embed.add_field(name="Label", value=image_data['label'], inline=True)
    embed.add_field(name="Proposed by", value=image_data['author'], inline=True)
    embed.set_image(url=image_data['path'])

    improve_player_stats(ctx)

    await ctx.respond(f"{ctx.author.mention} labeled observation **{id}** as **{label}**  πŸŽ‰ (Earned 10 XP)", embed=embed)

@bot.command(description="Get progress bar.")
async def progress(ctx):
    value = r.get(b'species_identified').decode('utf-8')
    progress_bar = generate_progress_bar(value)
    await ctx.respond(progress_bar) # this decorator makes a slash command

@bot.command(description="Get sound data.") # this decorator makes a slash command
async def sound(ctx, id): # a slash command will be created with the name "ping"
     # Fetch the sound data from Redis
    sound_data_bytes = r.hgetall(f'sound:{id}'.encode('utf-8'))
    sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Sound Observation {id} - Task", icon_url=ctx.author.display_avatar.url)
    embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
    embed.add_field(name="Label", value=sound_data['label'], inline=True)
    embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
    embed.add_field(name="Timestamp", value=sound_data['time'], inline=True)

    with open(sound_data['path'], 'rb') as f:
        sound = discord.File(f)
        message = await ctx.respond(file=sound, embed=embed)
        print('The ID of the message is:', message.id)

@bot.command(
        description="Label sound observation",
        options=[
            Option(name="id", description="The ID of the sound"),
            Option(name="label", description="The label for the sound"),
            Option(name="timestamp", description="The timestamp of the observation"),
    ])
async def label_sound(ctx, id:int, label:str, timestamp:str):
    r.hset(f'sound:{id}'.encode('utf-8'), b'label', label.encode('utf-8'))
    r.hset(f'sound:{id}'.encode('utf-8'), b'time', timestamp.encode('utf-8'))
    r.hset(f'sound:{id}'.encode('utf-8'), b'author', ctx.author.mention.encode('utf-8'))

    # Fetch the sound data from Redis
    sound_data_bytes = r.hgetall(f'sound:{id}'.encode('utf-8'))
    sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Sound Observation {id} - New Label πŸŽ‰", icon_url=ctx.author.display_avatar.url)
    embed.add_field(name="Sensor", value=sound_data['sensor'], inline=True)
    embed.add_field(name="Label", value=sound_data['label'], inline=True)
    embed.add_field(name="Proposed by", value=sound_data['author'], inline=True)
    embed.add_field(name="Time", value=sound_data['time'], inline=True)

    improve_player_stats(ctx)

    with open(sound_data['path'], 'rb') as f:
        sound = discord.File(f)
        await ctx.respond(f"{ctx.author.mention} labeled sound observation **{id}** as **{label}** at **{timestamp}**  πŸŽ‰ (Earned 10 XP)", file=sound, embed=embed)

@bot.command(
        description="List all unlabeled sound observations"
)
async def list_unlabeled_sound(ctx):

    unlabeled_ids = []

    # Fetch all the sound data from Redis
    keys = r.keys('sound:*'.encode('utf-8'))
    for key in keys:
        sound_data_bytes = r.hgetall(key)
        sound_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in sound_data_bytes.items()}
        if '❓' == sound_data['label']:
            unlabeled_ids = unlabeled_ids + [key.decode('utf-8')]

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Unlabeled Sound Observations", icon_url=ctx.author.display_avatar.url)

    for id in unlabeled_ids:
        embed.add_field(name=f"{id}", value="❓", inline=True)

    await ctx.respond(embed=embed)

@bot.command(
        description="List all unlabeled image observations"
)
async def list_unlabeled_image(ctx):

    unlabeled_ids = []

    # Fetch all the image data from Redis
    keys = r.keys('image:*'.encode('utf-8'))
    for key in keys:
        image_data_bytes = r.hgetall(key)
        image_data = {k.decode('utf-8'): v.decode('utf-8') for k, v in image_data_bytes.items()}
        if '❓' == image_data['label']:
            unlabeled_ids = unlabeled_ids + [key.decode('utf-8')]

    # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"Unlabeled Image Observations", icon_url=ctx.author.display_avatar.url)

    for id in unlabeled_ids:
        embed.add_field(name=f"{id}", value="❓", inline=True)

    await ctx.respond(embed=embed)

@bot.command(
        description="Check your profile"
    )
async def profile(ctx):
    xp_key = f'{ctx.author.name}:XP'.encode('utf-8')
    if not r.exists(xp_key):
        r.set(xp_key, 0)

    role_key = f'{ctx.author.name}:role'.encode('utf-8')
    if not r.exists(role_key):
        r.set(role_key, 'NATURALIST')

    oc_key = f'{ctx.author.name}:occurances'.encode('utf-8')
    if not r.exists(oc_key):
        r.set(oc_key, 0)

     # Create an embed
    embed = discord.Embed(color=discord.Colour.blurple())
    embed.set_author(name=f"{ctx.author.name} - Profile", icon_url=ctx.author.display_avatar.url)
    embed.add_field(name="**PROGRESS**", value=f"**Level**: 1\n**XP**: {r.get(xp_key).decode()}/1000\n", inline=False)
    embed.add_field(name="**STATS**", value=f"**🦜 Labels**: {r.get(oc_key).decode()}", inline=False)
    embed.set_thumbnail(url=ctx.author.display_avatar.url)
    embed.set_footer(text=f"πŸ† RANK: {r.get(role_key).decode()}")
    await ctx.respond(embed=embed)

    bot.run('MTA5NzMzMDI2MDI4NDAzNTEyMg.GNFiQP.hZC_2HLTvVAROlKKUmnVQjviT0G4wHeQq23-rs')