-
Notifications
You must be signed in to change notification settings - Fork 1
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
11 changed files
with
291 additions
and
275 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
81 changes: 81 additions & 0 deletions
81
Sources/ContributeWordPress/Decoder/WordPressSite+RSSChannel.swift
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,81 @@ | ||
import Foundation | ||
import SyndiKit | ||
|
||
extension WordPressSite { | ||
/// Returns the import directory name. | ||
public var importDirectoryName: String { | ||
baseURL.firstHostComponent ?? | ||
baseSiteURL?.firstHostComponent ?? | ||
"default" | ||
} | ||
|
||
/// Initializes a `WordPressSite` instance from an ``RSSChannel``. | ||
/// | ||
/// - Parameters: | ||
/// - channel: The `RSSChannel` instance. | ||
/// - Throws: An error if initialization fails. | ||
public init(channel: RSSChannel) throws { | ||
try self.init( | ||
channel: channel, | ||
relativeResourcePath: WordPressSite.wpContentUploadsRelativePath | ||
) | ||
} | ||
|
||
/// Initializes a `WordPressSite` instance from an ``RSSChannel`` with | ||
/// a relative resource path. | ||
/// | ||
/// - Parameters: | ||
/// - channel: The RSSChannel instance. | ||
/// - relativeResourcePath: The relative resource path. | ||
/// - Throws: An error if initialization fails. | ||
public init( | ||
channel: RSSChannel, | ||
relativeResourcePath: String | ||
) throws { | ||
let assetURLRegex = try Self.defaultAssetURLRegex( | ||
forSite: channel, | ||
relativeResourcePath: relativeResourcePath | ||
) | ||
self.init( | ||
title: channel.title, | ||
link: channel.link, | ||
categories: channel.wpCategories, | ||
tags: channel.wpTags, | ||
baseSiteURL: channel.wpBaseSiteURL, | ||
baseBlogURL: channel.wpBaseBlogURL, | ||
posts: channel.items.compactMap(\.wpPost), | ||
assetURLRegex: assetURLRegex | ||
) | ||
} | ||
|
||
/// Returns the default regular expression for matching asset urls. | ||
/// | ||
/// - Parameters: | ||
/// - site: The `BaseURLSite` instance. | ||
/// - relativeResourcePath: The relative resource path where assets would be located. | ||
/// - Returns: The default regular expression for matching asset urls. | ||
/// - Throws: An error if the regular expression cannot be created. | ||
public static func defaultAssetURLRegex( | ||
forSite site: BaseURLSite, | ||
relativeResourcePath: String = WordPressSite.wpContentUploadsRelativePath | ||
) throws -> NSRegularExpression { | ||
try Self.defaultAssetURLRegex( | ||
forAssetSiteURL: site.baseURL, | ||
relativeResourcePath: relativeResourcePath | ||
) | ||
} | ||
|
||
/// Returns the default regular expression for matching asset url. | ||
/// | ||
/// - Parameters: | ||
/// - assetSiteURL: The asset site URL. | ||
/// - relativeResourcePath: The relative resource path. | ||
/// - Returns: The default regular expression for matching asset url. | ||
/// - Throws: An error if the regular expression cannot be created. | ||
public static func defaultAssetURLRegex( | ||
forAssetSiteURL assetSiteURL: URL, | ||
relativeResourcePath: String = WordPressSite.wpContentUploadsRelativePath | ||
) throws -> NSRegularExpression { | ||
try NSRegularExpression(pattern: "\(assetSiteURL)/\(relativeResourcePath)([^\"]+)") | ||
} | ||
} |
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 was deleted.
Oops, something went wrong.
59 changes: 59 additions & 0 deletions
59
Sources/ContributeWordPress/Images/AssetImport+WordPress.swift
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,59 @@ | ||
import Foundation | ||
import SyndiKit | ||
|
||
extension AssetImport { | ||
/// Extracts asset imports from a ``WordPressSite`` using the specified import settings. | ||
/// | ||
/// - Parameters: | ||
/// - site: The WordPressSite instance. | ||
/// - importSettings: The ProcessorSettings instance. | ||
/// - Returns: An array of AssetImport instances. | ||
public static func extractAssetImports( | ||
from site: WordPressSite, | ||
using importSettings: ProcessorSettings | ||
) -> [AssetImport] { | ||
let assetRoot = [ | ||
"", | ||
importSettings.assetRelativePath, | ||
site.importDirectoryName | ||
].joined(separator: "/") | ||
return matchUrls( | ||
in: site.posts, | ||
using: site.assetURLRegex | ||
) | ||
.compactMap { match in | ||
AssetImport( | ||
forPost: match.post, | ||
sourceURL: match.sourceURL, | ||
assetRoot: assetRoot, | ||
resourcesPathURL: importSettings.resourcesPathURL, | ||
importPathURL: importSettings.importAssetPathURL | ||
) | ||
} | ||
} | ||
|
||
private static func matchUrls( | ||
in posts: [WordPressPost], | ||
using regex: NSRegularExpression | ||
) -> [(sourceURL: URL, post: WordPressPost)] { | ||
posts | ||
.flatMap { post in | ||
regex | ||
.matches( | ||
in: post.body, | ||
range: NSRange(post.body.startIndex..., in: post.body) | ||
) | ||
.compactMap { match in | ||
guard let range = Range(match.range, in: post.body) else { | ||
return nil | ||
} | ||
|
||
guard let url = URL(string: String(post.body[range])) else { | ||
return nil | ||
} | ||
|
||
return (sourceURL: url, post: post) | ||
} | ||
} | ||
} | ||
} |
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,5 @@ | ||
import Foundation | ||
|
||
/// A typealias that represents a factory function for creating asset imports. | ||
public typealias AssetImportFactory = | ||
(_ site: WordPressSite, _ importSettings: ProcessorSettings) -> [AssetImport] |
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,46 @@ | ||
import Contribute | ||
import Foundation | ||
import SyndiKit | ||
import Yams | ||
|
||
#if canImport(FoundationNetworking) | ||
import FoundationNetworking | ||
#endif | ||
|
||
/// A type that processes WordPress sites and generates Markdowns for their posts. | ||
extension MarkdownProcessor { | ||
/// Begins the processing of the WordPress posts. | ||
/// | ||
/// - Parameter settings: The required settings for processing WordPress exports. | ||
/// - Throws: An error if the processing failed at any step. | ||
public func begin( | ||
withSettings settings: ProcessorSettings | ||
) throws { | ||
// 1. Decodes WordPress site from exports directory. | ||
let allSites = try exportDecoder.sites(fromExportsAt: settings.exportsDirectoryURL) | ||
|
||
// 2. Writes redirects for all decoded WordPress posts. | ||
try redirectWriter.writeRedirects( | ||
fromSites: allSites, | ||
inDirectory: settings.resourcesPathURL | ||
) | ||
|
||
// 3. Extract and download asset imports for all WordPress sites. | ||
let assetImports: [AssetImport] = allSites.values.flatMap { | ||
assetImportFactory($0, settings) | ||
} | ||
|
||
try assetDownloader.download( | ||
assets: assetImports, | ||
dryRun: settings.skipDownload, | ||
allowsOverwrites: settings.overwriteAssets | ||
) | ||
|
||
// 4. Starts writing the markdown files for all WordPress posts for each site. | ||
try writeAllPosts( | ||
fromSites: allSites, | ||
withAssets: assetImports, | ||
withSettings: settings | ||
) | ||
} | ||
} |
Oops, something went wrong.