Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,15 +1,19 @@
|
|
| 1 |
-
import
|
| 2 |
-
import os
|
| 3 |
-
from pprint import pprint
|
| 4 |
-
from mastodon import Mastodon #Mastodon.py
|
| 5 |
|
|
|
|
| 6 |
auth_button_text = '''<a href="{}"><button class="w3-button w3-light-grey w3-padding-large w3-section " onclick="document.getElementById('download').style.display='block'">
|
| 7 |
-
<i class=""></i> Login with
|
| 8 |
</button></a><br>'''
|
| 9 |
|
|
|
|
| 10 |
def client_log_in():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
|
|
|
| 13 |
secret_file.write("{}\n".format(os.getenv('app_secret_1')))
|
| 14 |
secret_file.write("{}\n".format(os.getenv('app_secret_2')))
|
| 15 |
secret_file.write("https://infosec.exchange\n")
|
|
@@ -24,45 +28,43 @@ def client_log_in():
|
|
| 24 |
mastodon.log_in(
|
| 25 |
os.getenv('username'),
|
| 26 |
os.getenv('password'),
|
| 27 |
-
scopes=["write:blocks","write:mutes"],
|
| 28 |
redirect_uri="https://user1342-ivory.hf.space/",
|
| 29 |
)
|
| 30 |
|
| 31 |
return mastodon
|
| 32 |
|
|
|
|
| 33 |
def get_auth_url(mastodon):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
-
return mastodon.auth_request_url(client_id="ivory-secret.txt", scopes=["write:blocks","write:mutes"], redirect_uris="https://user1342-ivory.hf.space/")
|
| 36 |
|
| 37 |
def login_from_code(code):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
mastodon = Mastodon(
|
| 39 |
client_id="ivory-secret.txt",
|
| 40 |
api_base_url='https://infosec.exchange'
|
| 41 |
)
|
| 42 |
|
| 43 |
mastodon.log_in(code=code,
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
)
|
| 48 |
|
| 49 |
return mastodon
|
| 50 |
|
| 51 |
-
def get_posts_from_user(masterdom, user_id):
|
| 52 |
-
return masterdom.account_statuses(id=user_id)
|
| 53 |
-
|
| 54 |
|
| 55 |
-
#!/usr/bin/env python
|
| 56 |
# coding: utf-8
|
| 57 |
-
import json
|
| 58 |
-
import os
|
| 59 |
-
import re
|
| 60 |
-
import time
|
| 61 |
-
from random import random
|
| 62 |
-
import socket
|
| 63 |
-
|
| 64 |
-
from threading import Thread
|
| 65 |
-
from time import sleep
|
| 66 |
|
| 67 |
html_data = '''
|
| 68 |
<!DOCTYPE html>
|
|
@@ -134,11 +136,12 @@ function showDivs(n) {
|
|
| 134 |
# Imports
|
| 135 |
import json
|
| 136 |
import os
|
| 137 |
-
import time
|
| 138 |
import gradio as gr
|
| 139 |
|
| 140 |
# Setup the gradio block and add some generic CSS
|
| 141 |
-
block = gr.Blocks(
|
|
|
|
|
|
|
| 142 |
|
| 143 |
# Chat history variable used for the chatbot prompt on the 'getting started' page.
|
| 144 |
chat_history = []
|
|
@@ -146,26 +149,24 @@ chat_history = []
|
|
| 146 |
|
| 147 |
def get_client_from_tokens(code):
|
| 148 |
'''
|
| 149 |
-
This function is used for generating a
|
| 150 |
-
:param
|
| 151 |
-
:
|
| 152 |
-
:return: A Tweepy client object
|
| 153 |
'''
|
| 154 |
|
|
|
|
| 155 |
|
| 156 |
|
| 157 |
-
return login_from_code(code)
|
| 158 |
-
|
| 159 |
def block_user(user_id, user, reason):
|
| 160 |
finished = False
|
| 161 |
blocked = True
|
| 162 |
while not finished:
|
| 163 |
client.account_block(user_id)
|
| 164 |
|
| 165 |
-
|
| 166 |
print("Blocked {}, for {}".format(user, reason))
|
| 167 |
return blocked
|
| 168 |
|
|
|
|
| 169 |
def block_users(client, threshold, dataset):
|
| 170 |
'''
|
| 171 |
Used for blocking a series of users based on the threshold and datasets provided. Here the users folder is used.
|
|
@@ -184,37 +185,25 @@ def block_users(client, threshold, dataset):
|
|
| 184 |
|
| 185 |
for user in users:
|
| 186 |
print("Reviewing user {}".format(user))
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
if user["violence-threshold"] >= threshold:
|
| 200 |
-
user_id = str(user["username"])
|
| 201 |
-
if block_user(user_id, user, "Violent"):
|
| 202 |
-
num_users_blocked = num_users_blocked + 1
|
| 203 |
-
continue
|
| 204 |
-
if "Hate Speech" in dataset:
|
| 205 |
-
if user["toxicity-threshold"] >= threshold:
|
| 206 |
-
user_id = str(user["username"])
|
| 207 |
-
if block_user(user_id, user, "Hate Speech"):
|
| 208 |
-
num_users_blocked = num_users_blocked + 1
|
| 209 |
-
continue
|
| 210 |
-
|
| 211 |
|
| 212 |
return num_users_blocked
|
| 213 |
|
| 214 |
|
| 215 |
def chat(selected_option=None, radio_score=None, url_params=None):
|
| 216 |
'''
|
| 217 |
-
This function is used to initialise blocking users once the user has authenticated with
|
| 218 |
:param selected_option:
|
| 219 |
:param radio_score:
|
| 220 |
:param url_params:
|
|
@@ -243,7 +232,8 @@ def chat(selected_option=None, radio_score=None, url_params=None):
|
|
| 243 |
|
| 244 |
# Display to user, set options
|
| 245 |
history.append(
|
| 246 |
-
["Model tuned to a '{}%' threshold and is using the {} dataset.".format(radio_score,
|
|
|
|
| 247 |
"{} Account blocking initialised".format(block_type.capitalize())])
|
| 248 |
num_users_blocked = block_users(client, radio_score, selected_option)
|
| 249 |
history.append(
|
|
@@ -278,7 +268,7 @@ target_website = None
|
|
| 278 |
|
| 279 |
def update_target_website():
|
| 280 |
'''
|
| 281 |
-
Updates the URL used to authenticate WatchTower with
|
| 282 |
#TODO this function is full of old code and can be optimised.
|
| 283 |
:return:
|
| 284 |
'''
|
|
@@ -297,9 +287,9 @@ def update_target_website():
|
|
| 297 |
chatbot.value = chat_history
|
| 298 |
chatbot.update(value=chat_history)
|
| 299 |
|
| 300 |
-
|
| 301 |
get_target_website())
|
| 302 |
-
|
| 303 |
value=auth_button_text.format(
|
| 304 |
get_target_website()))
|
| 305 |
|
|
@@ -318,12 +308,14 @@ get_window_url_params = """
|
|
| 318 |
}
|
| 319 |
"""
|
| 320 |
|
|
|
|
| 321 |
def get_chatbot_text():
|
| 322 |
-
return [('Welcome to Watchtower.', 'Log in via
|
|
|
|
| 323 |
|
| 324 |
def get_target_website():
|
| 325 |
'''
|
| 326 |
-
A wrapper function used for retrieving the URL a user will use to authenticate WatchTower with
|
| 327 |
:return: auth url
|
| 328 |
'''
|
| 329 |
|
|
@@ -331,13 +323,11 @@ def get_target_website():
|
|
| 331 |
return get_auth_url(mastodon)
|
| 332 |
|
| 333 |
|
| 334 |
-
# The Gradio HTML component used for the 'sign in with
|
| 335 |
|
| 336 |
# The main chunk of code that uses Gradio blocks to create the UI
|
| 337 |
html_button = None
|
| 338 |
with block:
|
| 339 |
-
|
| 340 |
-
|
| 341 |
gr.HTML('''
|
| 342 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 343 |
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
|
@@ -351,22 +341,25 @@ with block:
|
|
| 351 |
with gr.Group():
|
| 352 |
with gr.Row().style(equal_height=True):
|
| 353 |
with gr.Box():
|
| 354 |
-
#gr.Label(value="WatchTower", visible=True, interactive=False)
|
| 355 |
url_params = gr.JSON({}, visible=False, label="URL Params").style(
|
| 356 |
)
|
| 357 |
text_input = gr.Text(label="Input", visible=False).style()
|
| 358 |
text_output = gr.Text(label="Output", visible=False).style()
|
| 359 |
-
html_button =
|
| 360 |
value=auth_button_text.format(
|
| 361 |
get_target_website())).style(
|
| 362 |
)
|
| 363 |
with gr.Row().style(equal_height=True):
|
| 364 |
-
radio = gr.CheckboxGroup(value=["Violent", "Hate Speech"],
|
| 365 |
-
|
|
|
|
| 366 |
|
| 367 |
slider = gr.Slider(value=30, interactive=True, label="Threshold Confidence Tolerance").style()
|
| 368 |
|
| 369 |
-
chatbot = gr.Chatbot(label="Watchtower Output", value=[('Welcome to Watchtower.',
|
|
|
|
|
|
|
| 370 |
|
| 371 |
btn = gr.Button("Run WatchTower").style(full_width=True).style()
|
| 372 |
btn.click(fn=button_pressed, inputs=[slider, url_params],
|
|
@@ -379,7 +372,7 @@ with block:
|
|
| 379 |
</p>"""
|
| 380 |
)
|
| 381 |
|
| 382 |
-
# Setup callback for when page loads (used to set a new
|
| 383 |
block.__enter__()
|
| 384 |
block.set_event_trigger(
|
| 385 |
event_name="load", fn=update_target_website, inputs=None, outputs=[html_button], no_target=True
|
|
@@ -392,4 +385,4 @@ block.set_event_trigger(
|
|
| 392 |
block.attach_load_events()
|
| 393 |
|
| 394 |
# Launcg the page
|
| 395 |
-
block.launch(enable_queue
|
|
|
|
| 1 |
+
from mastodon import Mastodon # Mastodon.py
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
# A HTML blob of text used to define the 'login in with' button
|
| 4 |
auth_button_text = '''<a href="{}"><button class="w3-button w3-light-grey w3-padding-large w3-section " onclick="document.getElementById('download').style.display='block'">
|
| 5 |
+
<i class=""></i> Login with Mastodon! 🐘
|
| 6 |
</button></a><br>'''
|
| 7 |
|
| 8 |
+
|
| 9 |
def client_log_in():
|
| 10 |
+
'''
|
| 11 |
+
Generates an authenticated Masterdon client for the admin user. Used for retireving the target website URL
|
| 12 |
+
:return: authenticated Masterdon client variable
|
| 13 |
+
'''
|
| 14 |
|
| 15 |
+
# Setup a 'secret' file used for persisting session between requests.
|
| 16 |
+
secret_file = open("ivory-secret.txt", "w")
|
| 17 |
secret_file.write("{}\n".format(os.getenv('app_secret_1')))
|
| 18 |
secret_file.write("{}\n".format(os.getenv('app_secret_2')))
|
| 19 |
secret_file.write("https://infosec.exchange\n")
|
|
|
|
| 28 |
mastodon.log_in(
|
| 29 |
os.getenv('username'),
|
| 30 |
os.getenv('password'),
|
| 31 |
+
scopes=["write:blocks", "write:mutes"],
|
| 32 |
redirect_uri="https://user1342-ivory.hf.space/",
|
| 33 |
)
|
| 34 |
|
| 35 |
return mastodon
|
| 36 |
|
| 37 |
+
|
| 38 |
def get_auth_url(mastodon):
|
| 39 |
+
'''
|
| 40 |
+
Retrieves a URL for the user to visit to auth them with WatchTower.
|
| 41 |
+
:param mastodon: A admin masterdon instance.
|
| 42 |
+
:return: The target URL.
|
| 43 |
+
'''
|
| 44 |
+
return mastodon.auth_request_url(client_id="ivory-secret.txt", scopes=["write:blocks", "write:mutes"],
|
| 45 |
+
redirect_uris="https://user1342-ivory.hf.space/")
|
| 46 |
|
|
|
|
| 47 |
|
| 48 |
def login_from_code(code):
|
| 49 |
+
'''
|
| 50 |
+
Used to create a masterdon client instance based on an authenticated user code (retrieved from the URL).
|
| 51 |
+
:param code: The code which will authenticate the user/ WatchTower.
|
| 52 |
+
:return: A masterdon client instance signed in as the user.
|
| 53 |
+
'''
|
| 54 |
mastodon = Mastodon(
|
| 55 |
client_id="ivory-secret.txt",
|
| 56 |
api_base_url='https://infosec.exchange'
|
| 57 |
)
|
| 58 |
|
| 59 |
mastodon.log_in(code=code,
|
| 60 |
+
scopes=["write:blocks", "write:mutes"],
|
| 61 |
+
redirect_uri="https://user1342-ivory.hf.space/")
|
|
|
|
|
|
|
| 62 |
|
| 63 |
return mastodon
|
| 64 |
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
# !/usr/bin/env python
|
| 67 |
# coding: utf-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
html_data = '''
|
| 70 |
<!DOCTYPE html>
|
|
|
|
| 136 |
# Imports
|
| 137 |
import json
|
| 138 |
import os
|
|
|
|
| 139 |
import gradio as gr
|
| 140 |
|
| 141 |
# Setup the gradio block and add some generic CSS
|
| 142 |
+
block = gr.Blocks(
|
| 143 |
+
css=".container { max-width: 800px; margin: auto; } h1 { margin: 0px; padding: 5px 0; line-height: 50px; font-size: 60pt; }.close-heading {margin: 0px; padding: 0px;} .close-heading p { margin: 0px; padding: 0px;}",
|
| 144 |
+
title="WatchTower")
|
| 145 |
|
| 146 |
# Chat history variable used for the chatbot prompt on the 'getting started' page.
|
| 147 |
chat_history = []
|
|
|
|
| 149 |
|
| 150 |
def get_client_from_tokens(code):
|
| 151 |
'''
|
| 152 |
+
This function is used for generating a masterdon client object based on the code URL paramiters
|
| 153 |
+
:param code
|
| 154 |
+
:return: A Masterdon client object
|
|
|
|
| 155 |
'''
|
| 156 |
|
| 157 |
+
return login_from_code(code)
|
| 158 |
|
| 159 |
|
|
|
|
|
|
|
| 160 |
def block_user(user_id, user, reason):
|
| 161 |
finished = False
|
| 162 |
blocked = True
|
| 163 |
while not finished:
|
| 164 |
client.account_block(user_id)
|
| 165 |
|
|
|
|
| 166 |
print("Blocked {}, for {}".format(user, reason))
|
| 167 |
return blocked
|
| 168 |
|
| 169 |
+
|
| 170 |
def block_users(client, threshold, dataset):
|
| 171 |
'''
|
| 172 |
Used for blocking a series of users based on the threshold and datasets provided. Here the users folder is used.
|
|
|
|
| 185 |
|
| 186 |
for user in users:
|
| 187 |
print("Reviewing user {}".format(user))
|
| 188 |
+
if "Violent" in dataset:
|
| 189 |
+
if user["violence-threshold"] >= threshold:
|
| 190 |
+
user_id = str(user["username"])
|
| 191 |
+
if block_user(user_id, user, "Violent"):
|
| 192 |
+
num_users_blocked = num_users_blocked + 1
|
| 193 |
+
continue
|
| 194 |
+
if "Hate Speech" in dataset:
|
| 195 |
+
if user["toxicity-threshold"] >= threshold:
|
| 196 |
+
user_id = str(user["username"])
|
| 197 |
+
if block_user(user_id, user, "Hate Speech"):
|
| 198 |
+
num_users_blocked = num_users_blocked + 1
|
| 199 |
+
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
return num_users_blocked
|
| 202 |
|
| 203 |
|
| 204 |
def chat(selected_option=None, radio_score=None, url_params=None):
|
| 205 |
'''
|
| 206 |
+
This function is used to initialise blocking users once the user has authenticated with Mastodon.
|
| 207 |
:param selected_option:
|
| 208 |
:param radio_score:
|
| 209 |
:param url_params:
|
|
|
|
| 232 |
|
| 233 |
# Display to user, set options
|
| 234 |
history.append(
|
| 235 |
+
["Model tuned to a '{}%' threshold and is using the {} dataset.".format(radio_score,
|
| 236 |
+
block_type.capitalize()),
|
| 237 |
"{} Account blocking initialised".format(block_type.capitalize())])
|
| 238 |
num_users_blocked = block_users(client, radio_score, selected_option)
|
| 239 |
history.append(
|
|
|
|
| 268 |
|
| 269 |
def update_target_website():
|
| 270 |
'''
|
| 271 |
+
Updates the URL used to authenticate WatchTower with Mastodon.
|
| 272 |
#TODO this function is full of old code and can be optimised.
|
| 273 |
:return:
|
| 274 |
'''
|
|
|
|
| 287 |
chatbot.value = chat_history
|
| 288 |
chatbot.update(value=chat_history)
|
| 289 |
|
| 290 |
+
mastodon_auth_button.value = auth_button_text.format(
|
| 291 |
get_target_website())
|
| 292 |
+
mastodon_auth_button.update(
|
| 293 |
value=auth_button_text.format(
|
| 294 |
get_target_website()))
|
| 295 |
|
|
|
|
| 308 |
}
|
| 309 |
"""
|
| 310 |
|
| 311 |
+
|
| 312 |
def get_chatbot_text():
|
| 313 |
+
return [('Welcome to Watchtower.', 'Log in via Mastodon and configure your blocking options above.')]
|
| 314 |
+
|
| 315 |
|
| 316 |
def get_target_website():
|
| 317 |
'''
|
| 318 |
+
A wrapper function used for retrieving the URL a user will use to authenticate WatchTower with Mastodon.
|
| 319 |
:return: auth url
|
| 320 |
'''
|
| 321 |
|
|
|
|
| 323 |
return get_auth_url(mastodon)
|
| 324 |
|
| 325 |
|
| 326 |
+
# The Gradio HTML component used for the 'sign in with Mastodon' button
|
| 327 |
|
| 328 |
# The main chunk of code that uses Gradio blocks to create the UI
|
| 329 |
html_button = None
|
| 330 |
with block:
|
|
|
|
|
|
|
| 331 |
gr.HTML('''
|
| 332 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 333 |
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
|
|
|
| 341 |
with gr.Group():
|
| 342 |
with gr.Row().style(equal_height=True):
|
| 343 |
with gr.Box():
|
| 344 |
+
# gr.Label(value="WatchTower", visible=True, interactive=False)
|
| 345 |
url_params = gr.JSON({}, visible=False, label="URL Params").style(
|
| 346 |
)
|
| 347 |
text_input = gr.Text(label="Input", visible=False).style()
|
| 348 |
text_output = gr.Text(label="Output", visible=False).style()
|
| 349 |
+
html_button = mastodon_auth_button = gr.HTML(
|
| 350 |
value=auth_button_text.format(
|
| 351 |
get_target_website())).style(
|
| 352 |
)
|
| 353 |
with gr.Row().style(equal_height=True):
|
| 354 |
+
radio = gr.CheckboxGroup(value=["Violent", "Hate Speech"],
|
| 355 |
+
choices=["Violent", "Hate Speech", "Misinformation"],
|
| 356 |
+
interactive=False, label="Behaviour To Block").style()
|
| 357 |
|
| 358 |
slider = gr.Slider(value=30, interactive=True, label="Threshold Confidence Tolerance").style()
|
| 359 |
|
| 360 |
+
chatbot = gr.Chatbot(label="Watchtower Output", value=[('Welcome to Watchtower.',
|
| 361 |
+
'Log in via Mastodon and configure your blocking options above.')]).style(
|
| 362 |
+
color_map=["grey", "purple"])
|
| 363 |
|
| 364 |
btn = gr.Button("Run WatchTower").style(full_width=True).style()
|
| 365 |
btn.click(fn=button_pressed, inputs=[slider, url_params],
|
|
|
|
| 372 |
</p>"""
|
| 373 |
)
|
| 374 |
|
| 375 |
+
# Setup callback for when page loads (used to set a new Mastodon auth target webspage)
|
| 376 |
block.__enter__()
|
| 377 |
block.set_event_trigger(
|
| 378 |
event_name="load", fn=update_target_website, inputs=None, outputs=[html_button], no_target=True
|
|
|
|
| 385 |
block.attach_load_events()
|
| 386 |
|
| 387 |
# Launcg the page
|
| 388 |
+
block.launch(enable_queue=True)
|