Skip to content

Commit

Permalink
Fetch and cache slack channels
Browse files Browse the repository at this point in the history
  • Loading branch information
ovv committed Jun 20, 2019
1 parent 06e8b7a commit ccad1c6
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 10 deletions.
10 changes: 7 additions & 3 deletions pyslackersweb/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ async def background_jobs(app: web.Application) -> None:
github_job = tasks.sync_github_repositories(app)
scheduler.add_job(github_job, "interval", hours=1)

slack_job = tasks.sync_slack_timezones(app)
scheduler.add_job(slack_job, "interval", hours=1)
slack_users_job = tasks.sync_slack_users(app)
scheduler.add_job(slack_users_job, "interval", hours=1)

slack_channels_job = tasks.sync_slack_channels(app)
scheduler.add_job(slack_channels_job, "interval", hours=1)

scheduler.start()

loop = asyncio.get_running_loop()
loop.create_task(github_job())
loop.create_task(slack_job())
loop.create_task(slack_users_job())
loop.create_task(slack_channels_job())

yield

Expand Down
81 changes: 74 additions & 7 deletions pyslackersweb/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ class Repository:
topics: List[str]


@dataclasses.dataclass(frozen=True) # pylint: disable=too-few-public-methods
class Channel:
id: str
name: str
topic: str
purpose: str
members: int


def sync_github_repositories(app: web.Application):
session = app["client_session"]

Expand Down Expand Up @@ -59,15 +68,15 @@ async def _sync_github() -> None:
return _sync_github


def sync_slack_timezones(app: web.Application):
def sync_slack_users(app: web.Application):
session = app["client_session"]

async def _sync_slack():
logger.debug("Refreshing slack user cache.")
async def _sync_slack_users():
logger.debug("Refreshing slack users cache.")
oauth_token = app["slack_token"]

if oauth_token is None:
logger.error("No slack oauth token set, unable to sync slack timezones.")
logger.error("No slack oauth token set, unable to sync slack users.")
return

try:
Expand All @@ -81,6 +90,10 @@ async def _sync_slack():
) as r:
result = await r.json()

if not result["ok"]:
logger.error("Error fetching users from slack", extra=result)
return

for user in result["members"]:
if user["deleted"] or user["is_bot"] or not user["tz"]:
continue
Expand All @@ -103,8 +116,62 @@ async def _sync_slack():
slack_timezones=dict(counter.most_common(100)),
slack_user_count=sum(counter.values()),
)
except Exception:
except Exception: # pylint: disable=broad-except
logger.exception("Error refreshing slack user cache")
raise
return

return _sync_slack_users


def sync_slack_channels(app: web.Application):
session = app["client_session"]

async def _sync_slack_channel():
logger.debug("Refreshing slack channels cache.")
oauth_token = app["slack_token"]

if oauth_token is None:
logger.error("No slack oauth token set, unable to sync slack channels.")
return

try:
channels = []
while True:
params = {}
async with session.get(
"https://slack.com/api/channels.list",
headers={"Authorization": f"Bearer {oauth_token}"},
params=params,
) as r:
result = await r.json()

if not result["ok"]:
logger.error("Error fetching channels from slack", extra=result)
return

for channel in result["channels"]:
channels.append(
Channel(
id=channel["id"],
name=channel["name"],
topic=channel["topic"]["value"],
purpose=channel["purpose"]["value"],
members=channel["num_members"],
)
)

# next_cursor can be an empty string. We need to check if the value is truthy
if result.get("response_metadata", {}).get("next_cursor"):
params["cursor"] = result["response_metadata"]["next_cursor"]
else:
break

logger.debug("Found %s slack channels", len(channels))

app.update(slack_channels=sorted(channels, key=lambda c: c.name))

except Exception: # pylint: disable=broad-except
logger.exception("Error refreshing slack channels cache")
return

return _sync_slack
return _sync_slack_channel

0 comments on commit ccad1c6

Please sign in to comment.