Beispiel #1
0
def test_load_post_body(schedule_file_storage_config):
    """Test loading of the Post body from a file."""
    schedule_file_storage = ScheduleFileStorage(schedule_file_storage_config)

    post_body = schedule_file_storage.load_post_body(POST_BODY_FILENAME)

    assert post_body == POST_BODY
Beispiel #2
0
def test_load_schedule_data(schedule_file_storage_config):
    """Test loading of the Schedule data from a file."""
    schedule_file_storage = ScheduleFileStorage(schedule_file_storage_config)

    schedule_data = schedule_file_storage.load_schedule_data()

    assert schedule_data == SCHEDULE_DATA
Beispiel #3
0
def test_load_schedule_data_error(tmpdir):
    """Test loading of the Schedule data from a nonexistent file."""
    schedule_path = tmpdir.join(SCHEDULE_FILENAME)
    config = MockConfig({"schedule_file": str(schedule_path)})

    schedule_file_storage = ScheduleFileStorage(config)

    assert not os.path.exists(schedule_path)

    with pytest.raises(MissingSchedule):
        schedule_file_storage.load_schedule_data()
Beispiel #4
0
def test_save_schedule_data(tmpdir):
    """Test saving of the Schedule data to a file."""
    schedule_path = tmpdir.join(SCHEDULE_FILENAME)
    config = MockConfig({"schedule_file": str(schedule_path)})

    schedule_file_storage = ScheduleFileStorage(config)

    assert not os.path.exists(schedule_path)

    schedule_file_storage.save_schedule_data(SCHEDULE_DATA)

    with open(schedule_path, encoding="utf-8") as schedule_file:
        schedule_data = schedule_file.read()

    assert schedule_data == SCHEDULE_DATA
Beispiel #5
0
def test_load_post_body_error(tmpdir):
    """Test loading of the Post body from a file."""
    schedule_path = tmpdir.join(SCHEDULE_FILENAME)
    post_body_path = tmpdir.join(POST_BODY_FILENAME)
    config = MockConfig({"schedule_file": str(schedule_path)})

    schedule_file_storage = ScheduleFileStorage(config)

    assert not os.path.exists(post_body_path)

    with pytest.raises(MissingPost) as missing_post_error:
        schedule_file_storage.load_post_body(POST_BODY_FILENAME)

    # Comply with PT012: https://pypi.org/project/flake8-pytest-style/
    assert str(post_body_path) in str(missing_post_error.value)  # noqa: WPS441
Beispiel #6
0
    def __init__(
        self,
        config: Config,
        reddit: Reddit,
    ) -> None:
        """Initialize Scheduler."""
        self.schedule: Optional[Schedule] = None
        self.reddit = reddit
        self.post_helper = PostHelper(config, reddit)

        self.schedule_storage: ScheduleStorage
        if config["schedule_wiki_url"]:
            self.schedule_storage = ScheduleWikiStorage(config, reddit)
        elif config["schedule_file"]:
            self.schedule_storage = ScheduleFileStorage(config)
        else:
            raise MissingSchedule(
                "Schedule storage not defined.",
                hint="The Schedule must be stored in a file or Reddit's wiki.",
            )
Beispiel #7
0
class Scheduler(object):
    """Manages data about scheduled posts."""
    def __init__(
        self,
        config: Config,
        reddit: Reddit,
    ) -> None:
        """Initialize Scheduler."""
        self.schedule: Optional[Schedule] = None
        self.reddit = reddit
        self.post_helper = PostHelper(config, reddit)

        self.schedule_storage: ScheduleStorage
        if config["schedule_wiki_url"]:
            self.schedule_storage = ScheduleWikiStorage(config, reddit)
        elif config["schedule_file"]:
            self.schedule_storage = ScheduleFileStorage(config)
        else:
            raise MissingSchedule(
                "Schedule storage not defined.",
                hint="The Schedule must be stored in a file or Reddit's wiki.",
            )

    def load(self) -> None:
        """Load the schedule from the storage."""
        self.schedule = self.schedule_storage.load()

    def get_scheduled_posts(self) -> Iterator[Post]:
        """Provide a generator of the scheduled posts."""
        while True:
            post = self.get_next_post()

            if not post:
                break

            yield post

    def get_next_post(self) -> Optional[Post]:
        """Find, prepare, and return the next scheduled posts."""
        if not self.schedule:
            raise RuntimeError(
                "The Schedule must be loaded before calling this method.", )

        current_time = datetime.utcnow()
        log.debug("get_next_post", after_time=current_time)

        for post in self.schedule.posts:
            if not post.submission_id and post.submit_at > current_time:
                next_post = post
                break
        else:
            return None

        self.post_helper.prepare_post(
            post=next_post,
            schedule=self.schedule,
            prepare_thumbnail=True,
        )

        return next_post

    def get_submitted_posts(
        self,
        skip_post: Optional[Post] = None,
    ) -> List[Post]:
        """Return a list of previously submitted posts."""
        if not self.schedule:
            raise RuntimeError(
                "The schedule must be loaded before calling this method.", )

        posts = []
        for post in self.schedule.posts:
            if skip_post and post.name == skip_post.name:
                continue

            if post.submission_id:
                self.post_helper.prepare_post(post, self.schedule)
                posts.append(post)

        return posts

    def save_schedule(self) -> None:
        """Save the schedule to the storage."""
        if not self.schedule:
            raise RuntimeError(
                "The schedule must be loaded before calling this method.", )

        self.schedule_storage.save(self.schedule)
Beispiel #8
0
def test_invalid_config():
    """Test initializing `ScheduleFileStorage` with invalid config."""
    config = MockConfig({"schedule_file": None})

    with pytest.raises(RuntimeError):
        ScheduleFileStorage(config)