Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
DreamCobbler committed Jan 2, 2021
2 parents efa332a + b90217d commit be8b79f
Show file tree
Hide file tree
Showing 56 changed files with 406 additions and 207 deletions.
15 changes: 15 additions & 0 deletions Docs/Changelogs.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# 1.8.0

**General:**

- **(Issue #11)** FF.net extractor ought to be able to download pages once more. f-dl now uses [cloudscraper](https://pypi.org/project/cloudscraper/) to bypass bot protection provided by Cloudflare.

**Extractors:**

- Added authentication support to the AO3 extractor.
- Reworked authentication using the XenForo extractor.

**Stuff:**

- Provided username and password are now remembered during the session by all the extractors using this method of authentication.

# 1.7.0

**General:**
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ![Logo](/Stuff/Logo%20(64).png?raw=true) [fiction-dl](https://github.com/DreamCobbler/fiction-dl) (*1.7.0*)
# ![Logo](/Stuff/Logo%20(64).png?raw=true) [fiction-dl](https://github.com/DreamCobbler/fiction-dl) (*1.8.0*)

![Screenshot (Windows 10)](/Stuff/Screenshot%20(Windows%2010).png?raw=true)
![Screenshot (Linux Mint 20)](/Stuff/Screenshot%20(Linux%20Mint%2020).png?raw=true)
Expand All @@ -25,7 +25,7 @@ In a select few sites, it allows you to log-in to the site using the command-lin

| \# | Category | Site | Authentication support | Channel support |
|------|------------------|---------------------------------------------------------------------|------------------------|--------------------------------|
| *1* | fanfiction | [Archive of Our Own](https://archiveofourown.org/) | ✗ no |**yes <sup>[1]</sup>** |
| *1* | fanfiction | [Archive of Our Own](https://archiveofourown.org/) | **yes** |**yes <sup>[1]</sup>** |
| *2* | fanfiction | [FanFiction.net](https://www.fanfiction.net/) | ✗ no |**yes <sup>[2]</sup>** |
| *3* | fanfiction | [FicWad.com](https://ficwad.com/) | ✗ no |**yes** |
| *4* | fanfiction | [SpaceBattles.com](https://forums.spacebattles.com/) |**yes** | ✗ no |
Expand Down
Binary file modified Stuff/Raw Screenshots/Linux Mint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Stuff/Raw Screenshots/Windows.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Stuff/Screenshot (Windows 10).png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions Tests/Integration Test Dataset 2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,6 @@ https://www.nifty.org/nifty/lesbian/adult-friends/sofie
#
##

# A single-chapter story.

https://www.quotev.com/story/13241547/Rain-on-fire

# A multi-chapter story.

https://www.quotev.com/story/13160599/Bloodlines
Expand Down
2 changes: 1 addition & 1 deletion Tests/Integration Test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Concepts/Chapter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
46 changes: 29 additions & 17 deletions fiction_dl/Concepts/Extractor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -30,17 +30,22 @@

from fiction_dl.Concepts.Chapter import Chapter
from fiction_dl.Concepts.Story import Story
import fiction_dl.Configuration as Configuration

# Standard packages.

from enum import Enum
import logging
import requests
from typing import List, Optional

# Non-standard packages.

from bs4 import BeautifulSoup
from dreamy_utilities.Web import DownloadSoup, GetHostname
from dreamy_utilities.Interface import Interface
from dreamy_utilities.Web import GetHostname
from dreamy_utilities.WebSession import WebSession
from fake_useragent import UserAgent

#
#
Expand All @@ -59,6 +64,17 @@

class Extractor:

##
#
# Represents authentication result.
#
##

class AuthenticationResult(Enum):
SUCCESS = 1
FAILURE = 2
ABANDONED = 3

def __init__(self) -> None:

##
Expand All @@ -69,7 +85,7 @@ def __init__(self) -> None:

self.Story = None

self._session = requests.session()
self._webSession = WebSession(UserAgent().random)
self._chapterURLs = []

self._downloadStorySoupWhenScanning = True
Expand Down Expand Up @@ -113,20 +129,19 @@ def SupportsAuthentication(self) -> bool:

return False

def Authenticate(self) -> bool:
def Authenticate(self, interface: Interface) -> AuthenticationResult:

##
#
# Logs the user in, interactively.
#
# @param username The username.
# @param password The password.
# @param interface The user interface to be used.
#
# @return **True** if the user has been authenticated correctly, **False** otherwise.
# @return The result of the authentication attempt.
#
##

return False
return AuthenticationResult.FAILURE

def Initialize(self, URL: str) -> bool:

Expand Down Expand Up @@ -180,9 +195,10 @@ def ScanStory(self) -> bool:

if self._downloadStorySoupWhenScanning:

soup = DownloadSoup(normalizedURL, self._session)
soup = self._webSession.GetSoup(normalizedURL)

if not soup:
logging.error(f'Failed to download page: "{normalizedURL}".')
logging.error(f'Failed to download tag soup: "{normalizedURL}".')
return False

return self._InternallyScanStory(normalizedURL, soup)
Expand Down Expand Up @@ -213,9 +229,9 @@ def ExtractChapter(self, index: int) -> Optional[Chapter]:

if self._downloadChapterSoupWhenExtracting:

soup = DownloadSoup(chapterURL, self._session, parser = self._chapterParserName)
soup = self._webSession.GetSoup(chapterURL, self._chapterParserName)
if not soup:
logging.error(f'Failed to download page: "{chapterURL}".')
logging.error(f'Failed to download tag soup: "{chapterURL}".')
return None

return self._InternallyExtractChapter(chapterURL, soup)
Expand All @@ -235,11 +251,7 @@ def ExtractMedia(self, URL: str) -> Optional[bytes]:
if not URL:
return None

response = self._session.get(URL, stream = True)
if not response.content:
return None

return response.content
return self._webSession.Get(URL, text = False, stream = True)

def _InternallyScanStory(
self,
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Concepts/Formatter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
4 changes: 2 additions & 2 deletions fiction_dl/Concepts/Image.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -218,7 +218,7 @@ def CreateImageFromDataUsingPIL(data: bytes, side: Optional[int] = None, quality
if side and (scale := side / max(width, height)) < 1:
image = image.resize(
(int(scale * width), int(scale * height)),
Image.ANTIALIAS
PIL.Image.ANTIALIAS
)

# Encode image data and store it.
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Concepts/Metadata.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Concepts/Processor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
6 changes: 3 additions & 3 deletions fiction_dl/Concepts/Story.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -31,7 +31,7 @@
from fiction_dl.Concepts.Image import Image
from fiction_dl.Concepts.Metadata import Metadata
from fiction_dl.Utilities.HTML import StripHTML
import fiction_dl.Configuration
import fiction_dl.Configuration as Configuration

# Standard packages.

Expand Down Expand Up @@ -89,7 +89,7 @@ def FillTemplate(self, template: str, escapeHTMLEntities: bool = False) -> str:
#
##

template = FillTemplate(fiction_dl.Configuration, template)
template = FillTemplate(Configuration, template)
template = FillTemplate(self.Metadata.GetPrettified(escapeHTMLEntities), template)

return template
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Concepts/StoryPackage.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
6 changes: 2 additions & 4 deletions fiction_dl/Configuration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -40,7 +40,7 @@
#

ApplicationName = "fiction-dl"
ApplicationVersion = "1.7.0"
ApplicationVersion = "1.8.0"
ApplicationShortDescription = (
"A content downloader, capable of retrieving works of (fan)fiction from the web and saving them in a few common file"
" formats."
Expand All @@ -50,8 +50,6 @@
CreatorName = "Benedykt Synakiewicz"
CreatorContact = "[email protected]"

UserAgent = f"{ApplicationName} {ApplicationVersion}"

RedditClientID = "ScszEQn1cI7GgQ"
RedditRedirectURI = "http://localhost:8080"

Expand Down
20 changes: 15 additions & 5 deletions fiction_dl/Core/Application.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,6 +29,7 @@
# Application.

from fiction_dl.Concepts.Chapter import Chapter
from fiction_dl.Concepts.Extractor import Extractor
from fiction_dl.Concepts.Story import Story
from fiction_dl.Concepts.StoryPackage import StoryPackage
from fiction_dl.Core.Cache import Cache
Expand Down Expand Up @@ -62,6 +63,7 @@

# Non-standard packages.

from cloudscraper.exceptions import CloudflareChallengeError
from dreamy_utilities.Containers import RemoveDuplicates
from dreamy_utilities.Filesystem import FindExecutable, GetSanitizedFileName, WriteTextFile
from dreamy_utilities.Interface import Interface
Expand Down Expand Up @@ -175,6 +177,11 @@ def Launch(self) -> None:
self._interface.Error(f"An SSL error has occurred: {caughtException}")
self._interface.GrabUserAttention()

except CloudflareChallengeError as caughtException:

self._interface.Error("A Cloudflare challenge error has occurred. Try again later.")
self._interface.GrabUserAttention()

except BaseException as caughtException:

self._interface.Error(f"An exception has been thrown: {caughtException}")
Expand Down Expand Up @@ -281,11 +288,14 @@ def _ProcessURL(self, URL: str) -> Optional[Story]:

if self._arguments.Authenticate and extractor.SupportsAuthentication():

self._interface.GrabUserAttention()
self._interface.Process("Logging-in...", section = True)

if not extractor.Authenticate():
self._interface.Error("Failed to authenticate.")
authenticationResult = extractor.Authenticate(self._interface)

if Extractor.AuthenticationResult.FAILURE == authenticationResult:
self._interface.Error("Failed to authenticate.")
elif Extractor.AuthenticationResult.ABANDONED == authenticationResult:
self._interface.Comment("Proceeding without logging-in...")
else:
self._interface.Comment("Authenticated successfully.")

Expand Down Expand Up @@ -397,7 +407,7 @@ def _ProcessURL(self, URL: str) -> Optional[Story]:
imageCount = len(extractor.Story.Images)
downloadedImageCount = 0

previousImageFailedToDownlod = False
previousImageFailedToDownload = False

for index, image in enumerate(extractor.Story.Images, start = 1):

Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Core/Cache.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Core/InputData.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion fiction_dl/Extractors/ExtractorAH.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
####
#
# fiction-dl
# Copyright (C) (2020) Benedykt Synakiewicz <[email protected]>
# Copyright (C) (2020 - 2021) Benedykt Synakiewicz <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down
Loading

0 comments on commit be8b79f

Please sign in to comment.