mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-02-26 08:27:38 +01:00
import OPML
This commit is contained in:
parent
c92b195cb8
commit
b6164c5af3
@ -3,7 +3,8 @@ import { connect } from "react-redux"
|
||||
import { createSelector } from "reselect"
|
||||
import { RootState } from "../../scripts/reducer"
|
||||
import GroupsTab from "../../components/settings/groups"
|
||||
import { createSourceGroup, SourceGroup, updateSourceGroup, addSourceToGroup, deleteSourceGroup, removeSourceFromGroup, reorderSourceGroups } from "../../scripts/models/page"
|
||||
import { createSourceGroup, SourceGroup, updateSourceGroup, addSourceToGroup,
|
||||
deleteSourceGroup, removeSourceFromGroup, reorderSourceGroups } from "../../scripts/models/page"
|
||||
|
||||
const getSources = (state: RootState) => state.sources
|
||||
const getGroups = (state: RootState) => state.page.sourceGroups
|
||||
|
@ -157,7 +157,7 @@ export function appReducer(
|
||||
fetchingItems: false,
|
||||
settings: {
|
||||
...state.settings,
|
||||
saving: false
|
||||
saving: action.batch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { RSSSource, SourceActionTypes, INIT_SOURCES, ADD_SOURCE, DELETE_SOURCE, addSource } from "./source"
|
||||
import fs = require("fs")
|
||||
import { SourceActionTypes, ADD_SOURCE, DELETE_SOURCE, addSource } from "./source"
|
||||
import { ALL, SOURCE } from "./feed"
|
||||
import { ActionStatus, AppThunk, domParser, AppDispatch } from "../utils"
|
||||
import fs = require("fs")
|
||||
import { saveSettings } from "./app"
|
||||
|
||||
const GROUPS_STORE_KEY = "sourceGroups"
|
||||
@ -204,11 +204,14 @@ export function reorderSourceGroups(groups: SourceGroup[]): AppThunk {
|
||||
}
|
||||
|
||||
async function outlineToSource(dispatch: AppDispatch, outline: Element): Promise<number> {
|
||||
let url = outline.getAttribute("xmlUrl").trim()
|
||||
let url = outline.getAttribute("xmlUrl")
|
||||
let name = outline.getAttribute("text") || outline.getAttribute("name")
|
||||
if (url) {
|
||||
let sid = await dispatch(addSource(url, name))
|
||||
return sid || null
|
||||
try {
|
||||
return await dispatch(addSource(url.trim(), name, true))
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
@ -221,9 +224,13 @@ export function importOPML(path: string): AppThunk {
|
||||
console.log(err)
|
||||
} else {
|
||||
dispatch(saveSettings())
|
||||
let successes: number, failures: number
|
||||
let doc = domParser.parseFromString(data, "text/xml")
|
||||
for (let el of doc.body.children) {
|
||||
let successes: number = 0, failures: number = 0
|
||||
let doc = domParser.parseFromString(data, "text/xml").getElementsByTagName("body")
|
||||
if (doc.length == 0) {
|
||||
dispatch(saveSettings())
|
||||
return
|
||||
}
|
||||
for (let el of doc[0].children) {
|
||||
if (el.getAttribute("type") === "rss") {
|
||||
let sid = await outlineToSource(dispatch, el)
|
||||
if (sid === null) failures += 1
|
||||
@ -231,15 +238,20 @@ export function importOPML(path: string): AppThunk {
|
||||
} else if (el.hasAttribute("text") || el.hasAttribute("title")) {
|
||||
let groupName = el.getAttribute("text") || el.getAttribute("title")
|
||||
let gid = dispatch(createSourceGroup(groupName))
|
||||
let sid = await outlineToSource(dispatch, el)
|
||||
if (sid === null) failures += 1
|
||||
else {
|
||||
for (let child of el.children) {
|
||||
let sid = await outlineToSource(dispatch, child)
|
||||
if (sid === null) {
|
||||
failures += 1
|
||||
} else {
|
||||
successes += 1
|
||||
dispatch(addSourceToGroup(gid, sid))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(failures, successes)
|
||||
dispatch(saveSettings())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,13 @@ export class RSSSource {
|
||||
|
||||
async fetchMetaData(parser: Parser) {
|
||||
let feed = await parser.parseURL(this.url)
|
||||
if (!this.name) this.name = feed.title.trim()
|
||||
if (!this.name && feed.title) this.name = feed.title.trim()
|
||||
this.description = feed.description
|
||||
let domain = this.url.split("/").slice(0, 3).join("/")
|
||||
let f = await faviconPromise(domain)
|
||||
let f: string = null
|
||||
try {
|
||||
f = await faviconPromise(domain)
|
||||
} finally {
|
||||
if (f === null) f = domain + "/favicon.ico"
|
||||
let result = await fetch(f)
|
||||
if (result.status == 200 && result.headers.has("Content-Type")
|
||||
@ -34,6 +37,7 @@ export class RSSSource {
|
||||
}
|
||||
return feed
|
||||
}
|
||||
}
|
||||
|
||||
private static checkItem(source: RSSSource, item: Parser.Item, db: Nedb<RSSItem>): Promise<RSSItem> {
|
||||
return new Promise<RSSItem>((resolve, reject) => {
|
||||
@ -92,6 +96,7 @@ interface InitSourcesAction {
|
||||
interface AddSourceAction {
|
||||
type: typeof ADD_SOURCE
|
||||
status: ActionStatus
|
||||
batch: boolean
|
||||
source?: RSSSource
|
||||
err?
|
||||
}
|
||||
@ -148,34 +153,37 @@ export function initSources(): AppThunk<Promise<void>> {
|
||||
}
|
||||
}
|
||||
|
||||
export function addSourceRequest(): SourceActionTypes {
|
||||
export function addSourceRequest(batch: boolean): SourceActionTypes {
|
||||
return {
|
||||
type: ADD_SOURCE,
|
||||
batch: batch,
|
||||
status: ActionStatus.Request
|
||||
}
|
||||
}
|
||||
|
||||
export function addSourceSuccess(source: RSSSource): SourceActionTypes {
|
||||
export function addSourceSuccess(source: RSSSource, batch: boolean): SourceActionTypes {
|
||||
return {
|
||||
type: ADD_SOURCE,
|
||||
batch: batch,
|
||||
status: ActionStatus.Success,
|
||||
source: source
|
||||
}
|
||||
}
|
||||
|
||||
export function addSourceFailure(err): SourceActionTypes {
|
||||
export function addSourceFailure(err, batch: boolean): SourceActionTypes {
|
||||
return {
|
||||
type: ADD_SOURCE,
|
||||
batch: batch,
|
||||
status: ActionStatus.Failure,
|
||||
err: err
|
||||
}
|
||||
}
|
||||
|
||||
export function addSource(url: string, name: string = null): AppThunk<Promise<void|number>> {
|
||||
export function addSource(url: string, name: string = null, batch = false): AppThunk<Promise<number>> {
|
||||
return (dispatch, getState) => {
|
||||
let app = getState().app
|
||||
if (app.sourceInit && !app.fetchingItems) {
|
||||
dispatch(addSourceRequest())
|
||||
dispatch(addSourceRequest(batch))
|
||||
let source = new RSSSource(url, name)
|
||||
return source.fetchMetaData(rssParser)
|
||||
.then(feed => {
|
||||
@ -186,7 +194,7 @@ export function addSource(url: string, name: string = null): AppThunk<Promise<vo
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
dispatch(addSourceSuccess(source))
|
||||
dispatch(addSourceSuccess(source, batch))
|
||||
RSSSource.checkItems(source, feed.items, db.idb)
|
||||
.then(items => insertItems(items))
|
||||
.then(items => {
|
||||
@ -200,7 +208,8 @@ export function addSource(url: string, name: string = null): AppThunk<Promise<vo
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e)
|
||||
dispatch(addSourceFailure(e))
|
||||
dispatch(addSourceFailure(e, batch))
|
||||
return new Promise((_, reject) => { reject(e) })
|
||||
})
|
||||
}
|
||||
return new Promise((_, reject) => { reject("Sources not initialized or fetching items.") })
|
||||
|
Loading…
x
Reference in New Issue
Block a user