Skip to content

Commit

Permalink
Merge pull request #44 from TogetherCrew/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
cyri113 authored Dec 22, 2023
2 parents 5294c14 + cfbb937 commit e50d3ab
Show file tree
Hide file tree
Showing 48 changed files with 771 additions and 729 deletions.
6 changes: 3 additions & 3 deletions analyzer_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class AnalyzerInit:
initialize the analyzer with its configs
"""

def __init__(self) -> None:
pass
def __init__(self, community_id: str) -> None:
self.community_id = community_id

def get_analyzer(self) -> tuple[RnDaoAnalyzer, dict[str, Any]]:
"""
Expand All @@ -23,7 +23,7 @@ def get_analyzer(self) -> tuple[RnDaoAnalyzer, dict[str, Any]]:
analyzer : RnDaoAnalyzer
mongo_creds : dict[str, Any]
"""
analyzer = RnDaoAnalyzer()
analyzer = RnDaoAnalyzer(self.community_id)

# credentials
mongo_creds = get_mongo_credentials()
Expand Down
18 changes: 16 additions & 2 deletions discord_analyzer/DB_operations/mongo_neo4j_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def set_neo4j_utils(
neo4j_port=port,
)
self.neo4j_ops.neo4j_database_connect()
logging.info("Neo4j Connected Successfully!")

def set_mongo_db_ops(
self, mongo_user: str, mongo_pass: str, mongo_host: str, mongo_port: str
Expand All @@ -49,9 +50,18 @@ def set_mongo_db_ops(
user=mongo_user, password=mongo_pass, host=mongo_host, port=mongo_port
)
self.mongoOps.set_mongo_db_access()
try:
info = self.mongoOps.mongo_db_access.db_mongo_client.server_info()
logging.info(f"MongoDB Connected, server info: {info}")
except Exception as exp:
logging.error(f"Error connecting to Mongodb, exp: {exp}")

def store_analytics_data(
self, analytics_data, remove_memberactivities=False, remove_heatmaps=False
self,
analytics_data: dict,
community_id: str,
remove_memberactivities: bool = False,
remove_heatmaps: bool = False,
):
"""
store the analytics data into database
Expand All @@ -65,6 +75,8 @@ def store_analytics_data(
heatmaps is also a list of dictinoaries
and memberactivities is a tuple of memberactivities dictionary list
and memebractivities networkx object dictionary list
community_id : str
the community id to save the data for
remove_memberactivities : bool
remove the whole memberactivity data and insert
default is `False` which means don't delete the existing data
Expand Down Expand Up @@ -98,7 +110,9 @@ def store_analytics_data(
and memberactivities_networkx_data != []
):
queries_list = make_neo4j_networkx_query_dict(
networkx_graphs=memberactivities_networkx_data, guildId=guildId
networkx_graphs=memberactivities_networkx_data,
guildId=guildId,
community_id=community_id,
)
self.run_operations_transaction(
guildId=guildId,
Expand Down
62 changes: 3 additions & 59 deletions discord_analyzer/DB_operations/mongodb_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,12 @@ def __init__(self) -> None:
"""
pass

def _check_inputs(
self,
acc_names,
channels,
dates,
variable_aggregation_type="and",
value_aggregation_type="or",
):
"""
just check whether the inputs are correctly entered or not
"""
# checking the length of arrays
if len(acc_names) < 1:
raise ValueError("acc_names array is empty!")
if len(channels) < 1:
raise ValueError("channels array is empty!")
if len(dates) < 1:
raise ValueError("dates array is empty!")

# checking the variable aggregation_type variable
if variable_aggregation_type not in ["and", "or"]:
raise ValueError(
f"variable aggregation type must be either `and` or \
`or`!\nentered value is:{variable_aggregation_type}"
)

# checking the value aggregation_type variable
if value_aggregation_type not in ["and", "or"]:
raise ValueError(
f"value aggregation type must be either `and` or \
`or`!\nentered value is:{value_aggregation_type}"
)

def create_query_filter_account_channel_dates(
self,
acc_names,
channels,
dates,
variable_aggregation_type="and",
value_aggregation_type="or",
date_key="date",
channel_key="channelId",
account_key="account_name",
Expand Down Expand Up @@ -94,35 +60,13 @@ def create_query_filter_account_channel_dates(
query : dictionary
the query to get access
"""

# creating each part of query seperately

# creating date query
date_query = []
for date in dates:
date_query.append({date_key: {"$regex": date}})

# creating channels query
channel_query = []

for ch in channels:
channel_query.append({channel_key: ch})

# creating the account_name query
account_query = []

for account in acc_names:
account_query.append({account_key: account})

# creating the query
query = {
"$"
+ variable_aggregation_type: [
{"$" + value_aggregation_type: account_query},
{"$" + value_aggregation_type: channel_query},
# for time we should definitly use `or` because
# `and` would result in nothing!
{"$or": date_query},
{account_key: {"$in": acc_names}},
{channel_key: {"$in": channels}},
{date_key: {"$in": dates}},
]
}

Expand Down
91 changes: 77 additions & 14 deletions discord_analyzer/DB_operations/network_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
import networkx


def make_neo4j_networkx_query_dict(networkx_graphs, guildId):
def make_neo4j_networkx_query_dict(
networkx_graphs: dict[datetime.datetime, networkx.classes.graph.Graph],
guildId: str,
community_id: str,
):
"""
make a list of queries to store networkx graphs into the neo4j
Expand All @@ -17,6 +21,8 @@ def make_neo4j_networkx_query_dict(networkx_graphs, guildId):
are the actual networkx graphs
guildId : str
the guild that the members belong to
community_id : str
the community id to save the data for
Returns:
-----------
Expand All @@ -34,6 +40,7 @@ def make_neo4j_networkx_query_dict(networkx_graphs, guildId):
networkx_graphs=graph_list,
networkx_dates=graph_dates,
guildId=guildId,
community_id=community_id,
toGuildRelation="IS_MEMBER",
)

Expand All @@ -44,6 +51,7 @@ def make_graph_list_query(
networkx_graphs: networkx.classes.graph.Graph,
networkx_dates: list[datetime.datetime],
guildId: str,
community_id: str,
toGuildRelation: str = "IS_MEMBER",
):
"""
Expand All @@ -59,6 +67,8 @@ def make_graph_list_query(
guildId : str
the guild that the members belong to
default is `None` meaning that it wouldn't be belonged to any guild
community_id : str
the community id to save the data for
toGuildRelation : str
the relationship label that connect the users to guilds
default value is `IS_MEMBER`
Expand All @@ -81,13 +91,46 @@ def make_graph_list_query(
guildId=guildId,
toGuildRelation=toGuildRelation,
)
community_query = create_community_node_query(community_id, guildId)

final_queries.extend(node_queries)
final_queries.extend(query_relations)
final_queries.append(community_query)

return final_queries


def create_community_node_query(
community_id: str,
guild_id: str,
community_node: str = "Community",
) -> str:
"""
create the community node
Parameters
------------
community_id : str
the community id to create its node
guild_id : str
the guild node to attach to community
"""
date_now_timestamp = get_timestamp()

query = f"""
MERGE (g:Guild {{guildId: '{guild_id}'}})
ON CREATE SET g.createdAt = {int(date_now_timestamp)}
WITH g
MERGE (c:{community_node} {{id: '{community_id}'}})
ON CREATE SET c.createdAt = {int(date_now_timestamp)}
WITH g, c
MERGE (g) -[r:IS_WITHIN]-> (c)
ON CREATE SET r.createdAt = {int(date_now_timestamp)}
"""

return query


def create_network_query(
nodes_dict: networkx.classes.reportviews.NodeDataView,
edge_dict: networkx.classes.reportviews.EdgeDataView,
Expand Down Expand Up @@ -127,19 +170,8 @@ def create_network_query(
the list of MERGE queries for creating all relationships
"""
# getting the timestamp `date`
graph_date_timestamp = (
graph_date.replace(
hour=0, minute=0, second=0, microsecond=0, tzinfo=datetime.timezone.utc
).timestamp()
* 1000
)
date_now_timestamp = (
datetime.datetime.now()
.replace(
hour=0, minute=0, second=0, microsecond=0, tzinfo=datetime.timezone.utc
)
.timestamp()
) * 1000
graph_date_timestamp = get_timestamp(graph_date)
date_now_timestamp = get_timestamp()

# initializiation of queries
rel_queries = []
Expand Down Expand Up @@ -208,3 +240,34 @@ def create_network_query(
rel_queries.append(rel_str_query + ";")

return node_queries, rel_queries


def get_timestamp(time: datetime.datetime | None = None) -> float:
"""
get the timestamp of the given time or just now
Parameters
------------
time : datetime.datetime
the time to get its timestamp
default is `None` meaning to send the time of now
Returns
--------
timestamp : float
the timestamp of the time multiplied to 1000
"""
using_time: datetime.datetime
if time is not None:
using_time = time
else:
using_time = datetime.datetime.now()

timestamp = (
using_time.replace(
hour=0, minute=0, second=0, microsecond=0, tzinfo=datetime.timezone.utc
).timestamp()
* 1000
)

return timestamp
11 changes: 6 additions & 5 deletions discord_analyzer/analysis/compute_interaction_matrix_discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Author Ene SS Rawa / Tjitse van der Molen

from discord_analyzer.analysis.utils.activity import Activity
from discord_analyzer.DB_operations.mongodb_access import DB_access
from discord_analyzer.DB_operations.mongodb_query import MongodbQuery
from numpy import ndarray

Expand All @@ -16,10 +17,10 @@


def compute_interaction_matrix_discord(
acc_names,
dates,
channels,
db_access,
acc_names: list[str],
dates: list[str],
channels: list[str],
db_access: DB_access,
activities: list[str] = [Activity.Mention, Activity.Reply, Activity.Reaction],
) -> dict[str, ndarray]:
"""
Expand Down Expand Up @@ -63,7 +64,7 @@ def compute_interaction_matrix_discord(
query_dict = query.create_query_filter_account_channel_dates(
acc_names=acc_names,
channels=channels,
dates=dates,
dates=list(dates),
date_key="date",
channel_key="channelId",
account_key="account_name",
Expand Down
Loading

0 comments on commit e50d3ab

Please sign in to comment.