Skip to content

Commit

Permalink
Merge pull request #51 from freedomofpress/add-flake8-black
Browse files Browse the repository at this point in the history
Add flake8, black, isort; GitHub action
  • Loading branch information
harrislapiroff authored Jul 19, 2023
2 parents 198c568 + b414a7e commit 2679fd9
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 82 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 100
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: CI
on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
apt-get update && apt-get install --yes --no-install-recommends make python3-pip
pip install black==23.7.0 flake8==6.0.0 isort==5.12.0
- name: Run lint
run: |
make lint-all
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.PHONY: flake8 isort isort-fix black black-fix lint-all

# Directory to run the linters on
DIR = .

flake8:
@echo "Running Flake8"
@flake8 $(DIR)

isort:
@echo "Running isort"
@isort --check --diff $(DIR)

isort-fix:
@echo "Running isort (fix)"
@isort $(DIR)

black:
@echo "Running Black"
@black --check $(DIR)

black-fix:
@echo "Running Black (fix)"
@black $(DIR)

lint-all: flake8 isort black
@echo "Linting complete"
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[tool.black]
line-length = 100
target-version = ['py39']
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ readability-lxml==0.8.1
requests==2.31.0
tweepy==4.14.0
Mastodon.py==1.8.1
black==23.7.0
flake8==6.0.0
isort==5.12.0
42 changes: 20 additions & 22 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
from setuptools import setup, find_packages
from setuptools import find_packages, setup

with open('requirements.txt') as f:
with open("requirements.txt") as f:
reqs = f.read().split()

with open('README.md') as f:
with open("README.md") as f:
readme = f.read()

setup(
name='trackthenews',
version='0.2',
description='Monitor RSS feeds for keywords and act on matching results. A special project of the Freedom of the Press Foundation.',
name="trackthenews",
version="0.2",
description="Monitor RSS feeds for keywords and act on matching results."
" A special project of the Freedom of the Press Foundation.",
long_description=readme,
long_description_content_type='text/markdown',
long_description_content_type="text/markdown",
install_requires=reqs,
author='Parker Higgins',
author_email='[email protected]',
url='https://github.com/freedomofpress/trackthenews',
entry_points={
'console_scripts': ['trackthenews=trackthenews:main']
},
package_data={
'trackthenews': ['fonts/*']
},
author="Parker Higgins",
author_email="[email protected]",
url="https://github.com/freedomofpress/trackthenews",
entry_points={"console_scripts": ["trackthenews=trackthenews:main"]},
package_data={"trackthenews": ["fonts/*"]},
include_package_data=True,
license='MIT',
license="MIT",
classifiers=[
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.9'],
packages=find_packages(exclude=('ttnconfig',))
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
],
packages=find_packages(exclude=("ttnconfig",)),
)
2 changes: 1 addition & 1 deletion trackthenews/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .core import *
from .core import main # noqa: F401
93 changes: 34 additions & 59 deletions trackthenews/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,26 @@

from __future__ import unicode_literals

from typing import IO, Iterable, List

import argparse
import json
import os
import sqlite3
import time
import textwrap
import sys

import textwrap
import time
from builtins import input
from datetime import datetime
from io import BytesIO, open
from builtins import input
from typing import IO, Iterable, List

import feedparser
import html2text
import requests
import tweepy
import yaml

from mastodon import Mastodon, MastodonError, MastodonNetworkError
from PIL import Image, ImageDraw, ImageFont
from readability import Document
from mastodon import Mastodon, MastodonNetworkError, MastodonError
import tweepy

# TODO: add/remove RSS feeds from within the script.
# Currently the matchwords list and RSS feeds list must be edited separately.
Expand Down Expand Up @@ -118,11 +115,7 @@ def truncate_alt_text(self, text, max_chars=1500):
"""Truncates the alt text to fit within the character limit."""
alt_text = "Excerpt: " + text
remaining_chars = max_chars - 3 # 3 chars for the ellipsis
alt_text = (
(alt_text[:remaining_chars] + "…")
if len(alt_text) > max_chars
else alt_text
)
alt_text = (alt_text[:remaining_chars] + "…") if len(alt_text) > max_chars else alt_text
return alt_text

def tweet(self):
Expand Down Expand Up @@ -165,9 +158,7 @@ def toot(self):
for idx, img_file in enumerate(img_files):
try:
alt_text = self.truncate_alt_text(self.matching_grafs[idx])
res = mastodon.media_post(
img_file, mime_type="image/jpeg", description=alt_text
)
res = mastodon.media_post(img_file, mime_type="image/jpeg", description=alt_text)
media_ids.append(res["id"])
except MastodonError:
pass
Expand Down Expand Up @@ -218,9 +209,7 @@ def get_twitter_client_v1():
oauth_token = config["twitter"]["oauth_token"]
oauth_token_secret = config["twitter"]["oauth_secret"]

tweepy_auth = tweepy.OAuth1UserHandler(
app_key, app_secret, oauth_token, oauth_token_secret
)
tweepy_auth = tweepy.OAuth1UserHandler(app_key, app_secret, oauth_token, oauth_token_secret)

return tweepy.API(tweepy_auth)

Expand All @@ -235,7 +224,7 @@ def upload_twitter_images(img_files: Iterable[IO]) -> List[tweepy.models.Media]:
try:
res = twitter.media_upload(filename="image", file=img)
media.append(res)
except tweepy.errors.TweepyException as e:
except tweepy.errors.TweepyException:
pass

return media
Expand Down Expand Up @@ -311,7 +300,6 @@ def parse_feed(outlet, url, delicate, redirects):


def config_twitter(config):

twitter_setup = input("Would you like the bot to post to Twitter? (Y/n) ")
if twitter_setup.lower().startswith("n"):
return config
Expand Down Expand Up @@ -425,24 +413,20 @@ def setup_matchlist():
with open(path, "w") as f:
f.write("")
print(
"A new matchlist has been generated at {path}. You can add case insensitive entries to match, one per line.".format(
**locals()
)
"A new matchlist has been generated at {path}."
" You can add case insensitive entries to match, one per line.".format(**locals())
)

if os.path.isfile(path_case_sensitive):
print(
"A case-sensitive matchlist already exists at {path_case_sensitive}.".format(
**locals()
)
"A case-sensitive matchlist already exists at {path_case_sensitive}.".format(**locals())
)
else:
with open(path_case_sensitive, "w") as f:
f.write("")
print(
"A new case-sensitive matchlist has been generated at {path_case_sensitive}. You can add case-sensitive entries to match, one per line.".format(
**locals()
)
"A new case-sensitive matchlist has been generated at {path_case_sensitive}."
" You can add case-sensitive entries to match, one per line.".format(**locals())
)

return
Expand All @@ -457,9 +441,7 @@ def setup_rssfeedsfile():
else:
with open(path, "w") as f:
f.write("")
print(
"A new RSS feeds file has been generated at {path}.".format(**locals())
)
print("A new RSS feeds file has been generated at {path}.".format(**locals()))

return

Expand All @@ -472,9 +454,9 @@ def initial_setup():
config = yaml.full_load(f)
else:
to_configure = input(
"It looks like this is the first time you've run trackthenews, or you've moved or deleted its configuration files.\nWould you like to create a new configuration in {}? (Y/n) ".format(
home
)
"It looks like this is the first time you've run trackthenews,"
" or you've moved or deleted its configuration files.\n"
"Would you like to create a new configuration in {}? (Y/n) ".format(home)
)

config = {}
Expand All @@ -487,15 +469,17 @@ def initial_setup():
else:
try:
os.makedirs(home)
except:
except Exception:
pass

if "db" not in config:
config["db"] = "trackthenews.db"

if "user-agent" not in config:
ua = input(
"What would you like your script's user-agent to be?\nThis should be something that is meaningful to you and may show up in the logs of the sites you are tracking: "
"What would you like your script's user-agent to be?\n"
"This should be something that is meaningful to you and"
" may show up in the logs of the sites you are tracking: "
)

ua = ua + " / powered by trackthenews (a project of freedom.press)"
Expand All @@ -516,9 +500,7 @@ def initial_setup():

# check if either Twitter or Mastodon has been configured
if "twitter" not in config and "mastodon" not in config:
print(
"Error: The bot must have at least one of Twitter or Mastodon configured."
)
print("Error: The bot must have at least one of Twitter or Mastodon configured.")
sys.exit(1)

with open(configfile, "w") as f:
Expand All @@ -540,12 +522,11 @@ def apply_migrations(conn):

def main():
parser = argparse.ArgumentParser(
description="Track articles from RSS feeds for a custom list of keywords and act on the matches."
description="Track articles from RSS feeds for a custom list of keywords"
" and act on the matches."
)

parser.add_argument(
"-c", "--config", help="Run configuration process", action="store_true"
)
parser.add_argument("-c", "--config", help="Run configuration process", action="store_true")
parser.add_argument(
"dir",
nargs="?",
Expand All @@ -563,7 +544,8 @@ def main():
if args.config:
initial_setup()
sys.exit(
"Created new configuration files. Now go populate the RSS Feed file and the list of matchwords!"
"Created new configuration files."
" Now go populate the RSS Feed file and the list of matchwords!"
)

configfile = os.path.join(home, "config.yaml")
Expand Down Expand Up @@ -599,9 +581,8 @@ def main():

if not (matchwords or matchwords_case_sensitive):
sys.exit(
"You must add words to at least one of the matchwords lists, located at {} and {}.".format(
matchlist, matchlist_case_sensitive
)
"You must add words to at least one of the matchwords lists,"
" located at {} and {}.".format(matchlist, matchlist_case_sensitive)
)

sys.path.append(home)
Expand Down Expand Up @@ -634,9 +615,7 @@ def main():
rss_feeds = json.load(f)
except json.JSONDecodeError:
sys.exit(
"You must add RSS feeds to the RSS feeds list, located at {}.".format(
rssfeedsfile
)
"You must add RSS feeds to the RSS feeds list, located at {}.".format(rssfeedsfile)
)

for feed in rss_feeds:
Expand All @@ -656,15 +635,11 @@ def main():
deduped.append(article)

for counter, article in enumerate(deduped, 1):
print(
"Checking {} article {}/{}".format(
article.outlet, counter, len(deduped)
)
)
print("Checking {} article {}/{}".format(article.outlet, counter, len(deduped)))

try:
article.check_for_matches()
except:
except Exception:
print("Having trouble with that article. Skipping for now.")
pass

Expand Down

0 comments on commit 2679fd9

Please sign in to comment.