Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pesacheck Meedan Bridge #549

Merged
merged 33 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6044b38
Add pesacheck script
koechkevin Feb 1, 2024
79e75e5
Add a cron job
koechkevin Feb 2, 2024
1d52ea7
Remove unwanted files
koechkevin Feb 2, 2024
a91cafa
Rename variables
koechkevin Feb 2, 2024
64c0da7
Lint and use pants
koechkevin Feb 2, 2024
918bdc0
Refactor and add docker build
koechkevin Feb 7, 2024
6763c0b
Add cron job, add .env
koechkevin Feb 8, 2024
dc73c8a
Bump boto3 from 1.34.31 to 1.34.32 in /3rdparty/py
dependabot[bot] Feb 1, 2024
2e72f8c
Bump boto3 from 1.34.32 to 1.34.33 in /3rdparty/py
dependabot[bot] Feb 2, 2024
68233fe
Bump boto3 from 1.34.33 to 1.34.34 in /3rdparty/py
dependabot[bot] Feb 5, 2024
10004d1
Bump boto3 from 1.34.34 to 1.34.35 in /3rdparty/py
dependabot[bot] Feb 6, 2024
de9879b
Bump boto3 from 1.34.35 to 1.34.36 in /3rdparty/py
dependabot[bot] Feb 7, 2024
8cdf376
Bump sentry-sdk from 1.40.0 to 1.40.2 in /3rdparty/py
dependabot[bot] Feb 7, 2024
09a5d3d
Merge branch 'main' into feature/pesacheck
koechkevin Feb 8, 2024
4d50048
Fix: Lint issues
koechkevin Feb 9, 2024
909fed8
Merge branch 'main' into feature/pesacheck
koechkevin Feb 9, 2024
1bc7dae
Fix docker lint issues
koechkevin Feb 9, 2024
4256526
Update files, fix lints
koechkevin Feb 9, 2024
da690f2
Update env.example
koechkevin Feb 9, 2024
04f3026
Merge branch 'main' into feature/pesacheck
koechkevin Feb 13, 2024
5b97306
Add local database
koechkevin Feb 13, 2024
a346d99
Build and deploy as a docker image
koechkevin Feb 14, 2024
f1e391b
Remove test data
koechkevin Feb 15, 2024
07fd4fb
Deploy app to dokku and test
koechkevin Feb 15, 2024
05face2
Fix lint issues
koechkevin Feb 15, 2024
ecf1c5c
- Use 1 database instance
koechkevin Feb 16, 2024
0637ba7
Pass whole database path as a url
koechkevin Feb 16, 2024
605a356
Update docker file
koechkevin Feb 16, 2024
bf3f2ce
Fix Graphql errors
koechkevin Feb 19, 2024
ecb97e1
Set default value in mutation queries
koechkevin Feb 20, 2024
6fd59db
Update language codes
koechkevin Feb 20, 2024
d9d835a
Remove credentials.json
koechkevin Feb 20, 2024
39359a9
add html2text parser
koechkevin Feb 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,6 @@ cython_debug/
### Pyenv ###

.python-version

# Custom gitignore
*.db
koechkevin marked this conversation as resolved.
Show resolved Hide resolved
# End of custom ignore
1 change: 1 addition & 0 deletions 3rdparty/py/requirements-all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ google-auth-httplib2==0.2.0
google-auth-oauthlib==1.2.0
greenlet==3.0.3
gunicorn[gevent, setproctitle]==21.2.0
html2text==2020.1.16
redis==5.0.1
requests==2.31.0
sentry-sdk==1.40.3
Expand Down
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ services:
depends_on:
- twoopstracker_app

pesacheck_meedan_bridge:
image: codeforafrica/pesacheck_meedan_bridge:latest
command: ["tail", "-f", "/dev/null"]
volumes:
- pesacheck-data:/app/database
env_file:
- ./pesacheck_meedan_bridge/.env

volumes:
app-media:
app-staticfiles:
db-data:
pesacheck-data:
2 changes: 2 additions & 0 deletions pants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ root_patterns = [
"/twoops_tracker/docker",
"/twoops_tracker/py",
"/pants-plugins",
"/pesacheck_meedan_bridge/py",
"/pesacheck_meedan_bridge/docker",
]

[python]
Expand Down
8 changes: 8 additions & 0 deletions pesacheck_meedan_bridge/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PESACHECK_URL=https://pesacheck.org/feed
PESACHECK_RSS2JSON_API_KEY=
PESACHECK_CHECK_URL=https://check-api.checkmedia.org/api/graphql
PESACHECK_CHECK_TOKEN=
PESACHECK_CHECK_WORKSPACE_SLUG=pesacheck-tipline-sandbox
PESACHECK_SENTRY_DSN=
PESACHECK_SENTRY_TRACES_SAMPLE_RATE=1.0
PESACHECK_SENTRY_ENVIRONMENT=local
32 changes: 32 additions & 0 deletions pesacheck_meedan_bridge/docker/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
docker_image(
name="pesacheck-deps",
image_tags=["deps"],
build_platform=["linux/amd64"],
registries=["pesacheck_meedan_bridge"],
repository="app",
skip_push=True,
source="Dockerfile.deps",
)

file(name="app.json", source="app.json")

docker_image(
name="pesacheck-srcs",
image_tags=["srcs"],
build_platform=["linux/amd64"],
registries=["pesacheck_meedan_bridge"],
repository="app",
skip_push=True,
source="Dockerfile.srcs",
)

docker_image(
name="pesacheck_meedan_bridge",
build_platform=["linux/amd64"],
dependencies=[":pesacheck-srcs", ":pesacheck-deps", ":app.json"],
image_tags=[
"{build_args.VERSION}",
"latest",
],
source="Dockerfile",
)
11 changes: 11 additions & 0 deletions pesacheck_meedan_bridge/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.11-slim-bullseye AS python-base
FROM pesacheck_meedan_bridge/app:deps AS app-deps
FROM pesacheck_meedan_bridge/app:srcs AS app-srcs
FROM python-base AS python-app

WORKDIR /app
COPY pesacheck_meedan_bridge/docker/app.json ./
COPY --from=app-deps /app ./
COPY --from=app-srcs /app ./

CMD ["tail", "-f", "/dev/null"]
4 changes: 4 additions & 0 deletions pesacheck_meedan_bridge/docker/Dockerfile.deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM python:3.11-slim-bookworm

COPY pesacheck_meedan_bridge.py/pesacheck-deps@environment=linux.pex /pesacheck-deps.pex
RUN PEX_TOOLS=1 python /pesacheck-deps.pex venv --scope=deps --compile /app
4 changes: 4 additions & 0 deletions pesacheck_meedan_bridge/docker/Dockerfile.srcs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM python:3.11-slim-bookworm

COPY pesacheck_meedan_bridge.py/pesacheck-srcs@environment=linux.pex /pesacheck-srcs.pex
RUN PEX_TOOLS=1 python /pesacheck-srcs.pex venv --scope=srcs --compile /app
9 changes: 9 additions & 0 deletions pesacheck_meedan_bridge/docker/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "pesacheck_meedan_bridge",
"cron": [
{
"command": "./pex",
"schedule": "@daily"
}
]
}
42 changes: 42 additions & 0 deletions pesacheck_meedan_bridge/py/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
python_sources(
name="lib",
dependencies=[
"3rdparty/py:requirements-all#requests",
"3rdparty/py:requirements-all#sentry-sdk",
"3rdparty/py:requirements-all#environs",
"3rdparty/py:requirements-all#html2text",
],
)

pex_binary(
name="pesacheck-deps",
environment=parametrize("__local__", "linux"),
dependencies=[
":lib",
],
entry_point="main.py",
include_sources=False,
include_tools=True,
layout="packed",
)

pex_binary(
name="pesacheck-srcs",
environment=parametrize("__local__", "linux"),
dependencies=[
":lib",
],
entry_point="main.py",
include_requirements=False,
include_tools=True,
layout="packed",
)


pex_binary(
name="pesacheck_meedan_bridge",
dependencies=[
":lib",
],
entry_point="main.py",
)
1 change: 1 addition & 0 deletions pesacheck_meedan_bridge/py/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
77 changes: 77 additions & 0 deletions pesacheck_meedan_bridge/py/check_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import json

import requests
import settings


def create_mutation_query(
media_type="Blank",
channel=None,
set_tags=[],
set_status="",
set_claim_description="",
title="",
summary="",
url="",
language="",
publish_report=False,
):
mutation_query = f"""
mutation create {{
createProjectMedia(input: {{
media_type: "{media_type}",
channel: {{ main: {channel} }},
set_tags: {json.dumps(set_tags)},
set_status: "{set_status}",
set_claim_description: \"\"\"{set_claim_description}\"\"\",
set_fact_check: {{
title: \"\"\"{title}\"\"\",
summary: \"\"\"{summary}\"\"\",
url: "{url}",
language: "{language}",
publish_report: {str(publish_report).lower()}
}}
}}) {{
project_media {{
id
full_url
claim_description {{
fact_check {{
id
}}
}}
}}
}}
}}
"""

return mutation_query


def delete_mutation_query(id):
mutation_query = f"""
mutation {{
destroyFactCheck(input: {{
id: "{id}"
}}) {{ deletedId }}
}}
"""
return mutation_query


def post_to_check(data):
query = create_mutation_query(**data)
headers = {
"Content-Type": "application/json",
"X-Check-Token": settings.PESACHECK_CHECK_TOKEN,
"X-Check-Team": settings.PESACHECK_CHECK_WORKSPACE_SLUG,
}
body = dict(query=query)
url = settings.PESACHECK_CHECK_URL
response = requests.post(url, headers=headers, json=body, timeout=60)
if response.status_code == 200:
res = response.json()
if res.get("errors"):
raise Exception(res["errors"])
return res
raise Exception(response.text)
139 changes: 139 additions & 0 deletions pesacheck_meedan_bridge/py/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import sqlite3
from dataclasses import dataclass
from sqlite3 import Error

import sentry_sdk
import settings


@dataclass
class PesacheckFeed:
title: str
pubDate: str
author: str
guid: str
link: str
thumbnail: str
description: str
status: str
categories: str
check_project_media_id: str = ""
check_full_url: str = ""
claim_description_id: str = ""


class PesacheckDatabase:
def __init__(self):
self.db_file = settings.PESACHECK_DATABASE_NAME
self.create_table()

def create_connection(self):
try:
conn = sqlite3.connect(self.db_file)
return conn
except Error as e:
sentry_sdk.capture_exception(e)
return None

def create_table(self):
conn = self.create_connection()
try:
cursor = conn.cursor()
cursor.execute(
"""CREATE TABLE IF NOT EXISTS pesacheck_feeds
(title TEXT NOT NULL,
pubDate TEXT NOT NULL,
author TEXT NOT NULL,
guid TEXT PRIMARY KEY,
link TEXT NOT NULL,
thumbnail TEXT NOT NULL,
description TEXT NOT NULL,
status TEXT DEFAULT 'Pending',
categories TEXT DEFAULT '[]',
check_project_media_id TEXT,
check_full_url TEXT,
claim_description_id TEXT)"""
)
conn.commit()
except Error as e:
sentry_sdk.capture_exception(e)
finally:
conn.close()

def insert_pesacheck_feed(self, feed):
conn = self.create_connection()
sql = """INSERT INTO pesacheck_feeds (title, pubDate, author,
guid, link, thumbnail, description, status, categories,
check_project_media_id, check_full_url, claim_description_id)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"""
try:
cur = conn.cursor()
cur.execute(
sql,
(
feed.title,
feed.pubDate,
feed.author,
feed.guid,
feed.link,
feed.thumbnail,
feed.description,
feed.status,
feed.categories,
feed.check_project_media_id,
feed.check_full_url,
feed.claim_description_id,
),
)
conn.commit()
except Error as e:
sentry_sdk.capture_exception(e)
finally:
conn.close()

def update_pesacheck_feed(self, guid, new_feed):
conn = self.create_connection()
sql = """UPDATE pesacheck_feeds
SET title = ?, pubDate = ?, author = ?, link = ?, thumbnail = ?,
description = ?, status = ?, categories = ?,
check_project_media_id = ?, check_full_url = ?,
claim_description_id = ? WHERE guid = ?"""
try:
cur = conn.cursor()
cur.execute(
sql,
(
new_feed.title,
new_feed.pubDate,
new_feed.author,
new_feed.link,
new_feed.thumbnail,
new_feed.description,
new_feed.status,
new_feed.categories,
new_feed.check_project_media_id,
new_feed.check_full_url,
new_feed.claim_description_id,
guid,
),
)
conn.commit()
except Error as e:
sentry_sdk.capture_exception(e)
finally:
conn.close()

def get_pending_pesacheck_feeds(self):
conn = self.create_connection()
try:
cur = conn.cursor()
cur.execute("SELECT * FROM pesacheck_feeds WHERE status = 'Pending'")
rows = cur.fetchall()
feeds = []
for row in rows:
feeds.append(PesacheckFeed(*row))
return feeds
except Error as e:
sentry_sdk.capture_exception(e)
finally:
conn.close()
Loading