Gregory Gundersen
5 years ago
12 changed files with 334 additions and 152 deletions
@ -0,0 +1,62 @@ |
|||
{ |
|||
"logging": { |
|||
"version": 1, |
|||
"disable_existing_loggers": true, |
|||
"formatters": { |
|||
"brief": { |
|||
"class": "logging.Formatter", |
|||
"style": "{", |
|||
"datefmt": "%H:%M:%S", |
|||
"format": "{name:s}-{levelname:s}-{asctime:s}-{message:s}" |
|||
}, |
|||
"verbose": { |
|||
"class": "logging.Formatter", |
|||
"style": "{", |
|||
"datefmt": "%Y-%m-%dT%H:%M:%S", |
|||
"format": "{name:s}:{levelname:s}:L{lineno:d} {asctime:s} {message:s}" |
|||
} |
|||
}, |
|||
"handlers": { |
|||
"console": { |
|||
"level": "DEBUG", |
|||
"class": "logging.StreamHandler", |
|||
"formatter": "brief", |
|||
"stream": "ext://sys.stdout" |
|||
}, |
|||
"file_handler": { |
|||
"level": "INFO", |
|||
"class": "logging.handlers.WatchedFileHandler", |
|||
"formatter": "verbose", |
|||
"filename": "./deletefb.log", |
|||
"mode": "a", |
|||
"encoding": "utf-8" |
|||
} |
|||
}, |
|||
"loggers": { |
|||
"root": { |
|||
"level": "DEBUG", |
|||
"handlers": ["console", "file_handler"] |
|||
}, |
|||
"deletefb": { |
|||
"level": "DEBUG", |
|||
"handlers": ["console"], |
|||
"propagate": false |
|||
}, |
|||
"login": { |
|||
"level": "DEBUG", |
|||
"handlers": ["file_handler"], |
|||
"propagate": false |
|||
}, |
|||
"likes": { |
|||
"level": "DEBUG", |
|||
"handlers": ["file_handler"], |
|||
"propagate": false |
|||
}, |
|||
"wall": { |
|||
"level": "DEBUG", |
|||
"handlers": ["file_handler"], |
|||
"propagate": false |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
from .config import settings |
|||
from contextlib import contextmanager |
|||
from pathlib import Path |
|||
|
|||
import attr |
|||
import json |
|||
|
|||
# Used to avoid duplicates in the log |
|||
from pybloom_live import BloomFilter |
|||
|
|||
def make_filter(): |
|||
return BloomFilter( |
|||
capacity=settings["MAX_POSTS"], |
|||
error_rate=0.001 |
|||
) |
|||
|
|||
@attr.s |
|||
class Archive: |
|||
archive_type = attr.ib() |
|||
|
|||
# We give the Archive class a file handle |
|||
archive_file = attr.ib() |
|||
|
|||
_bloom_filter = attr.ib(factory=make_filter) |
|||
|
|||
def archive(self, content): |
|||
""" |
|||
Archive an object |
|||
""" |
|||
print("Archiving {0}".format(content)) |
|||
|
|||
if content.name not in self._bloom_filter: |
|||
self.archive_file.write(json.dumps(attr.asdict(content)) + "\n") |
|||
self._bloom_filter.add(content.name) |
|||
return |
|||
|
|||
@contextmanager |
|||
def archiver(archive_type): |
|||
|
|||
archive_file = open( |
|||
(Path(".") / Path(archive_type).name).with_suffix(".log"), |
|||
mode="ta", |
|||
buffering=1 |
|||
) |
|||
|
|||
archiver_instance = Archive( |
|||
archive_type=archive_type, |
|||
archive_file=archive_file |
|||
) |
|||
|
|||
try: |
|||
yield archiver_instance |
|||
finally: |
|||
archive_file.close() |
@ -0,0 +1,4 @@ |
|||
settings = { |
|||
"ARCHIVE" : True, |
|||
"MAX_POSTS" : 5000 |
|||
} |
@ -0,0 +1,29 @@ |
|||
import attr |
|||
import uuid |
|||
import datetime |
|||
|
|||
def timestamp_now(): |
|||
""" |
|||
Returns: a timestamp for this instant, in ISO 8601 format |
|||
""" |
|||
return datetime.datetime.isoformat(datetime.datetime.now()) |
|||
|
|||
# Data type definitions of posts and comments |
|||
@attr.s |
|||
class Post: |
|||
content = attr.ib() |
|||
comments = attr.ib(default=[]) |
|||
date = attr.ib(factory=timestamp_now) |
|||
name = attr.ib(factory=lambda: uuid.uuid4().hex) |
|||
|
|||
@attr.s |
|||
class Comment: |
|||
commenter = attr.ib() |
|||
content = attr.ib() |
|||
date = attr.ib(factory=timestamp_now) |
|||
name = attr.ib(factory=lambda: uuid.uuid4().hex) |
|||
|
|||
@attr.s |
|||
class Page: |
|||
name = attr.ib() |
|||
date = attr.ib(factory=timestamp_now) |
Loading…
Reference in new issue