-
Notifications
You must be signed in to change notification settings - Fork 58
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
3 changed files
with
271 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
"use strict"; | ||
import { createWriteStream, mkdirSync } from "hexo-fs"; | ||
import createLogger from "hexo-log"; | ||
import path from "path"; | ||
import { generate } from "./lib/generate"; | ||
|
||
const supported_types = ["book", "movie", "game", "song"]; | ||
|
||
const log = createLogger({ | ||
debug: false, | ||
silent: false, | ||
}); | ||
|
||
// Register `hexo g` and `hexo s` | ||
supported_types.forEach((type) => { | ||
hexo.extend.generator.register(`${type}s`, function (locals) { | ||
if ( | ||
!this.config.douban || | ||
!this.config.douban[type] || | ||
!this.config.douban.builtin | ||
) { | ||
return; | ||
} | ||
|
||
let path = this.config.douban[type].path; | ||
if (path) { | ||
this.config.douban[type].path = path.replace(/^\//, ""); | ||
} else { | ||
this.config.douban[type].path = `${type}s/index.html`; | ||
} | ||
return generate( | ||
this.config.lang, | ||
this.config.url, | ||
type, | ||
this.config.douban | ||
) as any; | ||
}); | ||
}); | ||
|
||
const options = { | ||
options: [ | ||
{ name: "-b, --books", desc: "Generate douban books only" }, | ||
{ name: "-m, --movies", desc: "Generate douban movies only" }, | ||
{ name: "-g, --games", desc: "Generate douban games only" }, | ||
{ name: "-s, --songs", desc: "Generate douban songs only" }, | ||
], | ||
}; | ||
|
||
// Register `hexo douban` | ||
hexo.extend.console.register( | ||
"douban", | ||
"Generate pages from douban", | ||
options, | ||
function (args) { | ||
if (!this.config.douban) { | ||
log.info("No douban config specified"); | ||
return; | ||
} | ||
if (!this.config.douban.id) { | ||
log.info("No douban id specified"); | ||
return; | ||
} | ||
|
||
let force_types: string[] = []; | ||
supported_types.forEach((supported_type) => { | ||
if ( | ||
(Object.keys(args).includes(supported_type[0]) || | ||
Object.keys(args).includes(`${supported_type}s`)) && | ||
this.config.douban[supported_type] | ||
) { | ||
force_types.push(supported_type); | ||
} | ||
}); | ||
|
||
let enabled_types: string[] = []; | ||
|
||
if (force_types.length !== 0) { | ||
enabled_types = force_types; | ||
} else { | ||
supported_types.forEach((type) => { | ||
if (this.config.douban[type]) { | ||
enabled_types.push(type); | ||
} | ||
}); | ||
} | ||
|
||
if (enabled_types.length === 0) { | ||
log.info("No douban type specified"); | ||
return; | ||
} | ||
|
||
// Prepare path | ||
enabled_types.forEach((type) => { | ||
let path = this.config.douban[type].path; | ||
if (path) { | ||
this.config.douban[type].path = path.replace(/^\//, ""); | ||
} else { | ||
this.config.douban[type].path = `${type}s/index.html`; | ||
} | ||
|
||
hexo.extend.generator.register(type, function (locals) { | ||
return generate( | ||
this.config.lang, | ||
this.config.url, | ||
type, | ||
this.config.douban | ||
) as any; | ||
}); | ||
}); | ||
|
||
const self = this; | ||
|
||
//Generate files | ||
self.load().then(function () { | ||
enabled_types.forEach((type) => { | ||
const publicDir = self.public_dir; | ||
const id = self.config.douban[type].path; | ||
mkdirSync(path.join(publicDir, id.replace("index.html", "")), { | ||
recursive: true, | ||
}); | ||
|
||
let stream = self.route.get(id); | ||
if (stream) { | ||
self.route.get(id).pipe(createWriteStream(path.join(publicDir, id))); | ||
log.info("Generated: %s", id); | ||
} | ||
}); | ||
}); | ||
} | ||
); |
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,121 @@ | ||
import idouban from "idouban"; | ||
import { DoubanConfig, TypeConfig } from "./types"; | ||
import createLogger from "hexo-log"; | ||
import Handlebars from "handlebars"; | ||
import { readFileSync } from "hexo-fs"; | ||
|
||
const template: string = `<div id="idouban"></div> | ||
<style type="text/css"> | ||
{{{style}}} | ||
</style> | ||
<script> | ||
/*<!--*/ | ||
{{{script}}} | ||
/*-->*/ | ||
</script> | ||
<script> | ||
/*<!--*/ | ||
idouban.init({{{init}}}) | ||
/*-->*/ | ||
</script> | ||
`; | ||
|
||
const escape_html = (unsafe: string) => { | ||
return unsafe; | ||
}; | ||
|
||
const log = createLogger({ | ||
debug: false, | ||
silent: false, | ||
}); | ||
|
||
export async function generate( | ||
lang: string, | ||
url: string, | ||
type: string, | ||
config: DoubanConfig | ||
) { | ||
if (!config.item_per_page) { | ||
config.item_per_page = 10; | ||
} | ||
|
||
if (!config.meta_max_line) { | ||
config.meta_max_line = 4; | ||
} | ||
|
||
if (!config.customize_layout) { | ||
config.customize_layout = "page"; | ||
} | ||
|
||
const available_actions = ["do", "wish", "collect"]; | ||
const type_config = config[type] as TypeConfig; | ||
|
||
if (type_config.actions && type_config.actions.length !== 0) { | ||
type_config.actions = type_config.actions.filter((action) => | ||
available_actions.includes(action) | ||
); | ||
if (type_config.actions.length === 0) { | ||
type_config.actions = available_actions; | ||
} | ||
} else { | ||
type_config.actions = available_actions; | ||
} | ||
|
||
const script = readFileSync( | ||
"../node_modules/idouban/dist/index.js" | ||
) as string; | ||
const style = readFileSync( | ||
"../node_modules/idouban/dist/index.css" | ||
) as string; | ||
|
||
const init_config = { | ||
selector: "#idouban", | ||
lang: lang, | ||
douban_id: config.id, | ||
type: type, | ||
quote: type_config.quote, | ||
page_size: config.item_per_page, | ||
max_line: config.meta_max_line, | ||
}; | ||
|
||
if (config.dynamic) { | ||
init_config["actions"] = type_config.actions; | ||
} else { | ||
const startTime = new Date().getTime(); | ||
|
||
let data_list = await idouban.fetchData( | ||
config.id, | ||
url, | ||
type, | ||
type_config.actions | ||
); | ||
init_config["data_list"] = data_list; | ||
const endTime = new Date().getTime(); | ||
|
||
log.info( | ||
`${data_list.map( | ||
(data) => data.action + "(" + data.items.length + ")" | ||
)} ${type} loaded in ${endTime - startTime} ms` | ||
); | ||
} | ||
|
||
const renderer = Handlebars.compile(template); | ||
const dom = renderer({ | ||
style: style, | ||
script: escape_html(script), | ||
init: JSON.stringify(init_config), | ||
}); | ||
|
||
return { | ||
path: type_config.path, | ||
data: Object.assign( | ||
{ | ||
title: type_config.title, | ||
content: dom, | ||
slug: `${type}s`, | ||
}, | ||
type_config.option | ||
), | ||
layout: [config.customize_layout, "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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export interface TypeConfig { | ||
path: string; | ||
actions: string[]; | ||
title: string; | ||
quote: string; | ||
option: any; | ||
} | ||
|
||
export interface DoubanConfig { | ||
id: string; | ||
builtin: boolean; | ||
dynamic: boolean; | ||
item_per_page: number; | ||
meta_max_line: number; | ||
customize_layout: string; | ||
book: TypeConfig; | ||
movie: TypeConfig; | ||
game: TypeConfig; | ||
song: TypeConfig; | ||
} |