Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
mythsman committed May 27, 2024
1 parent 47a0268 commit cf8f10f
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 0 deletions.
130 changes: 130 additions & 0 deletions index.ts
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);
}
});
});
}
);
121 changes: 121 additions & 0 deletions lib/generate.ts
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"],
};
}
20 changes: 20 additions & 0 deletions lib/types.ts
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;
}

0 comments on commit cf8f10f

Please sign in to comment.