-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
289 additions
and
323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
from asphalt.core import Component, run_application | ||
|
||
|
||
class ServerComponent(Component): | ||
async def start(self) -> None: | ||
print("Hello, world!") | ||
|
||
|
||
if __name__ == "__main__": | ||
component = ServerComponent() | ||
run_application(component) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# isort: off | ||
import logging | ||
|
||
import anyio | ||
import httpx | ||
from asphalt.core import CLIApplicationComponent, run_application | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ApplicationComponent(CLIApplicationComponent): | ||
async def run(self) -> None: | ||
async with httpx.AsyncClient() as http: | ||
while True: | ||
await http.get("https://imgur.com") | ||
await anyio.sleep(10) | ||
|
||
|
||
if __name__ == "__main__": | ||
run_application(ApplicationComponent(), logging=logging.DEBUG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
import logging | ||
from typing import Any | ||
|
||
import anyio | ||
import httpx | ||
from asphalt.core import CLIApplicationComponent, run_application | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ApplicationComponent(CLIApplicationComponent): | ||
async def run(self) -> None: | ||
last_modified = None | ||
async with httpx.AsyncClient() as http: | ||
while True: | ||
headers: dict[str, Any] = ( | ||
{"if-modified-since": last_modified} if last_modified else {} | ||
) | ||
response = await http.get("https://imgur.com", headers=headers) | ||
logger.debug("Response status: %d", response.status_code) | ||
if response.status_code == 200: | ||
last_modified = response.headers["date"] | ||
logger.info("Contents changed") | ||
|
||
await anyio.sleep(10) | ||
|
||
|
||
if __name__ == "__main__": | ||
run_application(ApplicationComponent(), logging=logging.DEBUG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
import logging | ||
from difflib import unified_diff | ||
from typing import Any | ||
|
||
import anyio | ||
import httpx | ||
from asphalt.core import CLIApplicationComponent, run_application | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ApplicationComponent(CLIApplicationComponent): | ||
async def run(self) -> None: | ||
async with httpx.AsyncClient() as http: | ||
last_modified, old_lines = None, None | ||
while True: | ||
logger.debug("Fetching webpage") | ||
headers: dict[str, Any] = ( | ||
{"if-modified-since": last_modified} if last_modified else {} | ||
) | ||
response = await http.get("https://imgur.com", headers=headers) | ||
logger.debug("Response status: %d", response.status_code) | ||
if response.status_code == 200: | ||
last_modified = response.headers["date"] | ||
new_lines = response.text.split("\n") | ||
if old_lines is not None and old_lines != new_lines: | ||
difference = unified_diff(old_lines, new_lines) | ||
logger.info("Contents changed:\n%s", difference) | ||
|
||
old_lines = new_lines | ||
|
||
await anyio.sleep(10) | ||
|
||
|
||
if __name__ == "__main__": | ||
run_application(ApplicationComponent(), logging=logging.DEBUG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
import logging | ||
from difflib import HtmlDiff | ||
from typing import Any | ||
|
||
import anyio | ||
import httpx | ||
from asphalt.core import CLIApplicationComponent, run_application | ||
from asphalt.core import inject, resource | ||
from asphalt.mailer import Mailer | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ApplicationComponent(CLIApplicationComponent): | ||
async def start(self) -> None: | ||
self.add_component( | ||
"mailer", | ||
backend="smtp", | ||
host="your.smtp.server.here", | ||
message_defaults={"sender": "[email protected]", "to": "[email protected]"}, | ||
) | ||
await super().start() | ||
|
||
@inject | ||
async def run(self, *, mailer: Mailer = resource()) -> None: | ||
async with httpx.AsyncClient() as http: | ||
last_modified, old_lines = None, None | ||
diff = HtmlDiff() | ||
while True: | ||
logger.debug("Fetching webpage") | ||
headers: dict[str, Any] = ( | ||
{"if-modified-since": last_modified} if last_modified else {} | ||
) | ||
response = await http.get("https://imgur.com", headers=headers) | ||
logger.debug("Response status: %d", response.status_code) | ||
if response.status_code == 200: | ||
last_modified = response.headers["date"] | ||
new_lines = response.text.split("\n") | ||
if old_lines is not None and old_lines != new_lines: | ||
difference = diff.make_file(old_lines, new_lines, context=True) | ||
await mailer.create_and_deliver( | ||
subject="Change detected in web page", html_body=difference | ||
) | ||
logger.info("Sent notification email") | ||
|
||
old_lines = new_lines | ||
|
||
await anyio.sleep(10) | ||
|
||
|
||
if __name__ == "__main__": | ||
run_application(ApplicationComponent(), logging=logging.DEBUG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
from dataclasses import dataclass | ||
|
||
from asphalt.core import Event | ||
|
||
|
||
@dataclass | ||
class WebPageChangeEvent(Event): | ||
old_lines: list[str] | ||
new_lines: list[str] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# isort: off | ||
from __future__ import annotations | ||
|
||
import logging | ||
from dataclasses import dataclass | ||
from typing import Any | ||
|
||
import anyio | ||
import httpx | ||
|
||
from asphalt.core import Event, Signal | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@dataclass | ||
class WebPageChangeEvent(Event): | ||
old_lines: list[str] | ||
new_lines: list[str] | ||
|
||
|
||
class Detector: | ||
changed = Signal(WebPageChangeEvent) | ||
|
||
def __init__(self, url: str, delay: float): | ||
self.url = url | ||
self.delay = delay | ||
|
||
async def run(self) -> None: | ||
async with httpx.AsyncClient() as http: | ||
last_modified, old_lines = None, None | ||
while True: | ||
logger.debug("Fetching contents of %s", self.url) | ||
headers: dict[str, Any] = ( | ||
{"if-modified-since": last_modified} if last_modified else {} | ||
) | ||
response = await http.get("https://imgur.com", headers=headers) | ||
logger.debug("Response status: %d", response.status_code) | ||
if response.status_code == 200: | ||
last_modified = response.headers["date"] | ||
new_lines = response.text.split("\n") | ||
if old_lines is not None and old_lines != new_lines: | ||
self.changed.dispatch(WebPageChangeEvent(old_lines, new_lines)) | ||
|
||
old_lines = new_lines | ||
|
||
await anyio.sleep(self.delay) |
Oops, something went wrong.