Skip to content

Commit dd00357

Browse files
committed
Sirbot
1 parent a839b10 commit dd00357

19 files changed

+1146
-14
lines changed

.env.sample

-1
This file was deleted.

Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ RUN apk add --no-cache tzdata gcc g++ make postgresql-dev build-base git && \
1111
echo "UTC" >> /etc/timezone && \
1212
apk del tzdata
1313

14+
RUN apk add --no-cache libffi-dev git
15+
1416
COPY requirements requirements
1517
RUN pip install -r requirements/development.txt
1618

docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ services:
1212
DATABASE_URL: "postgresql://${USER}:@postgresql:5432/pyslackers_dev"
1313
SLACK_INVITE_TOKEN: "${SLACK_INVITE_TOKEN}"
1414
SLACK_TOKEN: "${SLACK_TOKEN}"
15+
SLACK_SIGNING_SECRET: "${SLACK_SIGNING_SECRET}"
1516
ports:
1617
- "8000:8000"
1718
volumes:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"""empty message
2+
3+
Revision ID: 5b03cd946e60
4+
Revises: 3df042324a1f
5+
Create Date: 2020-03-01 20:33:03.352360+00:00
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import postgresql
11+
12+
# revision identifiers, used by Alembic.
13+
revision = "5b03cd946e60"
14+
down_revision = "3df042324a1f"
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table(
22+
"slack_channels",
23+
sa.Column("id", sa.Text(), nullable=False),
24+
sa.Column("name", sa.Text(), nullable=True),
25+
sa.Column("created", sa.DateTime(timezone=True), nullable=True),
26+
sa.Column("archived", sa.Boolean(), nullable=True),
27+
sa.Column("members", sa.Integer(), nullable=True),
28+
sa.Column("topic", sa.Text(), nullable=True),
29+
sa.Column("purpose", sa.Text(), nullable=True),
30+
sa.PrimaryKeyConstraint("id"),
31+
sa.UniqueConstraint("name"),
32+
)
33+
op.create_index("ix_slack_channels_id", "slack_channels", ["id"], unique=False)
34+
op.create_index("ix_slack_channels_name", "slack_channels", ["name"], unique=False)
35+
36+
op.create_table(
37+
"slack_messages",
38+
sa.Column("id", sa.Text(), nullable=False),
39+
sa.Column("send_at", sa.DateTime(), nullable=True),
40+
sa.Column("user", sa.Text(), nullable=True),
41+
sa.Column("channel", sa.Text(), nullable=True),
42+
sa.Column("message", sa.Text(), nullable=True),
43+
sa.Column("raw", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
44+
sa.PrimaryKeyConstraint("id"),
45+
)
46+
op.create_index(
47+
"ix_slack_messages_channel", "slack_messages", ["channel", "send_at"], unique=False
48+
)
49+
op.create_index("ix_slack_messages_user", "slack_messages", ["user", "send_at"], unique=False)
50+
op.create_index(
51+
"ix_slack_messages_user_channel",
52+
"slack_messages",
53+
["user", "channel", "send_at"],
54+
unique=False,
55+
)
56+
57+
op.create_table(
58+
"slack_users",
59+
sa.Column("id", sa.Text(), nullable=False),
60+
sa.Column("name", sa.Text(), nullable=True),
61+
sa.Column("deleted", sa.Boolean(), nullable=True),
62+
sa.Column("admin", sa.Boolean(), nullable=True),
63+
sa.Column("bot", sa.Boolean(), nullable=True),
64+
sa.Column("timezone", sa.Text(), nullable=True),
65+
sa.Column("first_seen", sa.DateTime(timezone=True), nullable=True),
66+
sa.PrimaryKeyConstraint("id"),
67+
sa.UniqueConstraint("name"),
68+
)
69+
op.create_index("ix_slack_users_admin", "slack_users", ["id", "admin"], unique=False)
70+
op.create_index("ix_slack_users_id", "slack_users", ["id"], unique=False)
71+
op.create_index("ix_slack_users_name", "slack_users", ["id", "name"], unique=False)
72+
op.create_index("ix_slack_users_timezone", "slack_users", ["id", "timezone"], unique=False)
73+
# ### end Alembic commands ###
74+
75+
76+
def downgrade():
77+
# ### commands auto generated by Alembic - please adjust! ###
78+
op.drop_index("ix_slack_users_timezone", table_name="slack_users")
79+
op.drop_index("ix_slack_users_name", table_name="slack_users")
80+
op.drop_index("ix_slack_users_id", table_name="slack_users")
81+
op.drop_index("ix_slack_users_admin", table_name="slack_users")
82+
op.drop_table("slack_users")
83+
84+
op.drop_index("ix_slack_messages_user_channel", table_name="slack_messages")
85+
op.drop_index("ix_slack_messages_user", table_name="slack_messages")
86+
op.drop_index("ix_slack_messages_channel", table_name="slack_messages")
87+
op.drop_table("slack_messages")
88+
89+
op.drop_index("ix_slack_channels_name", table_name="slack_channels")
90+
op.drop_index("ix_slack_channels_id", table_name="slack_channels")
91+
op.drop_table("slack_channels")
92+
# ### end Alembic commands ###

pyslackersweb/models.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ class Source(Enum):
5050
"slack_users",
5151
metadata,
5252
sa.Column("id", sa.Text, primary_key=True),
53+
sa.Column("name", sa.Text),
5354
sa.Column("deleted", sa.Boolean),
5455
sa.Column("admin", sa.Boolean),
5556
sa.Column("bot", sa.Boolean),
5657
sa.Column("timezone", sa.Text),
5758
sa.Column("first_seen", sa.DateTime(timezone=True), default=datetime.now),
5859
sa.Index("ix_slack_users_id", "id"),
59-
sa.Index("ix_slack_users_admin", "id", "admin"),
60-
sa.Index("ix_slack_users_timezone", "id", "timezone"),
60+
sa.Index("ix_slack_users_name", "name"),
61+
sa.Index("ix_slack_users_id_admin", "id", "admin"),
62+
sa.Index("ix_slack_users_id_timezone", "id", "timezone"),
6163
)

pyslackersweb/sirbot/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import logging
2+
13
from aiohttp import web
24

35
from .views import routes
46
from .context import background_jobs
57

8+
logger = logging.getLogger(__name__)
9+
610

711
async def app_factory() -> web.Application:
812
sirbot = web.Application()

pyslackersweb/sirbot/database.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import logging
22

33
import asyncpg
4+
import sqlalchemy as sa
45

6+
from pyslackersweb import models
57
from pyslackersweb.util.log import ContextAwareLoggerAdapter
68

79

@@ -15,3 +17,6 @@ async def get_challenge(conn: asyncpg.connection.Connection) -> str:
1517
SELECT id FROM codewars_challenge WHERE posted_at IS NULL ORDER BY RANDOM() LIMIT 1
1618
) RETURNING id""",
1719
)
20+
21+
async def is_admin(conn: asyncpg.connection.Connection, user: str) -> bool:
22+
return await conn.fetchval(sa.select([models.SlackUsers.c.admin]).where(id=user))

pyslackersweb/sirbot/models.py

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import sqlalchemy as sa
2+
3+
import dataclasses
4+
15
from datetime import datetime
6+
from typing import Optional
7+
from decimal import Decimal
28

3-
import sqlalchemy as sa
9+
from sqlalchemy.dialects.postgresql import JSONB
410

511
from pyslackersweb.models import metadata
612

@@ -17,3 +23,35 @@
1723
nullable=True,
1824
),
1925
)
26+
27+
@dataclasses.dataclass(frozen=True)
28+
class StockQuote:
29+
# pylint: disable=too-many-instance-attributes
30+
31+
symbol: str
32+
company: str
33+
price: Decimal
34+
change: Decimal
35+
change_percent: Decimal
36+
market_open: Decimal
37+
market_close: Decimal
38+
high: Decimal
39+
low: Decimal
40+
volume: Decimal
41+
time: datetime
42+
logo: Optional[str] = None
43+
44+
45+
SlackMessage = sa.Table(
46+
"slack_messages",
47+
metadata,
48+
sa.Column("id", sa.Text, primary_key=True),
49+
sa.Column("send_at", sa.DateTime),
50+
sa.Column("user", sa.Text),
51+
sa.Column("channel", sa.Text),
52+
sa.Column("message", sa.Text),
53+
sa.Column("raw", JSONB),
54+
sa.Index("ix_slack_messages_user", "user", "send_at"),
55+
sa.Index("ix_slack_messages_channel", "channel", "send_at"),
56+
sa.Index("ix_slack_messages_user_channel", "user", "channel", "send_at"),
57+
)

pyslackersweb/sirbot/settings.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import os
22

3-
# production
3+
IS_PRODUCTION = os.environ.get("PLATFORM_BRANCH") == "master"
4+
5+
# production settings
46
READTHEDOCS_NOTIFICATION_CHANNEL = "community_projects"
7+
SLACK_TEAM_ID = os.environ.get("SLACK_TEAM_ID")
8+
SLACK_SIGNING_SECRET = os.environ.get("SLACK_SIGNING_SECRET", "")
9+
SLACK_ADMIN_CHANNEL = os.environ.get("SLACK_ADMIN_CHANNEL", "")
10+
SLACK_INTRODUCTION_CHANNEL = "introductions"
511

6-
# Development
7-
if os.environ.get("PLATFORM_BRANCH") != "master":
12+
# Development settings
13+
if not IS_PRODUCTION:
814
READTHEDOCS_NOTIFICATION_CHANNEL = "general"
15+
SLACK_ADMIN_CHANNEL = "CJ1BWMBDX" # general
16+
SLACK_INTRODUCTION_CHANNEL = "general"

0 commit comments

Comments
 (0)