zoukankan      html  css  js  c++  java
  • 博客园备份提取

    简述

    在博客园记录了一些文章,想把它备份到github上,还好大部分博文都是markdown格式的,博客园也支持备份导出,但是到处的是单个的XML文件。
    为了把每一篇博文单独提取出来,所以写了一个小程序来提取。

    github中需要如下图所示的格式,方能正确的分类

    文件名需要日期开头,文件内容中最前面一段是文章的一些描述信息

    程序代码

    程序是用Golang编写的,代码如下:

    // cnblogs2githubpages project main.go
    package main
    
    import (
    	"bytes"
    	"encoding/xml"
    	"fmt"
    	"io/ioutil"
    	"os"
    	"strings"
    	"time"
    )
    
    // 结构体中要能够进行XML解析,则字段名必须以大写开头
    // 帖子
    type Post struct {
    	XMLName     xml.Name `xml:"item"`
    	Title       string   `xml:"title"`
    	Link        string   `xml:"link"`
    	Creator     string   `xml:"dc:creator"`
    	Author      string   `xml:"author"`
    	PubDate     string   `xml:"pubDate"`
    	Guid        string   `xml:"guid"`
    	Description string   `xml:"description,CDATA"`
    }
    
    type Blogs struct {
    	XMLName       xml.Name `xml:"channel"`
    	Title         string   `xml:"title"`
    	Link          string   `xml:"link"`
    	Description   string   `xml:"description"`
    	Language      string   `xml:"language"`
    	LastBuildDate string   `xml:"lastBuildDate"`
    	PubDate       string   `xml:"pubDate"`
    	Ttl           string   `xml:"ttl"`
    	Items         []Post   `xml:"item"`
    }
    type RSS struct {
    	XMLName xml.Name `xml:"rss"`
    	Blogs   Blogs    `xml:"channel"`
    }
    
    func main() {
    	if len(os.Args) != 2 {
    		return
    	}
    	backupxml, err := ioutil.ReadFile(os.Args[1])
    	if err != nil {
    		fmt.Println(err.Error())
    		return
    	}
    	fmt.Println(len(backupxml))
    
    	b := RSS{}
    
    	err = xml.Unmarshal(backupxml, &b)
    	if err != nil {
    		fmt.Println(err.Error())
    		return
    	}
    	fmt.Println(len(b.Blogs.Items))
    
            // 逐个导出
    	for i, _ := range b.Blogs.Items {
    		var item = &(b.Blogs.Items[i])
    		t, _ := time.Parse(time.RFC1123, item.PubDate)
    		postdate := t.Format("2006-01-02")
    		// fmt.Printf("%s
    	%s
    	%s
    	%s
    	%s
    ", date, item.Title, item.Link, item.Author, item.Description[0:64])
    		postTitle := strings.ReplaceAll(item.Title, " ", "-")
    		postTitle = strings.ReplaceAll(postTitle, "*", "")
    		postTitle = strings.ReplaceAll(postTitle, "/", ".")
    		postTitle = strings.ReplaceAll(postTitle, "\", "")
    		postTitle = strings.ReplaceAll(postTitle, "$", "")
    		postTitle = strings.ReplaceAll(postTitle, "?", "")
    		postTitle = strings.ReplaceAll(postTitle, ":", "-")
    		postTitle = strings.ReplaceAll(postTitle, "。", "")
    		filename := fmt.Sprintf("./%s-%s.md", postdate, postTitle)
    		fmt.Println(filename)
                     
                    // 根据博文的标题,做一个简单的分类(只适合当前情况)
    		var categories string = "其它"
    		{
    			title2 := strings.ToLower(item.Title)
    			if strings.Contains(title2, "live555") {
    				categories = "live555"
    			} else if strings.Contains(title2, "linux") || strings.Contains(title2, "ubuntu") {
    				categories = "linux"
    			} else if strings.Contains(title2, "gcc") || strings.Contains(title2, "git") ||
    				strings.Contains(title2, "编程") || strings.Contains(title2, "编译") ||
    				strings.Contains(title2, "vc") || strings.Contains(title2, "c++") ||
    				strings.Contains(title2, "visual") || strings.Contains(title2, "程序") {
    				categories = "编程"
    			} else if strings.Contains(title2, "gdal") || strings.Contains(title2, "proj") ||
    				strings.Contains(title2, "gis") || strings.Contains(title2, "地理") {
    				categories = "地理信息"
    			}
    		}
    		var desc bytes.Buffer
    
    		desc.WriteString("---
    ")
    		desc.WriteString("layout:  post
    ")
    		desc.WriteString("title:  "")
    		desc.WriteString(item.Title)
    		desc.WriteString(""
    date:  ")
    		desc.WriteString(postdate)
    		desc.WriteString("
    categories:  ")
    		desc.WriteString(categories)
    		desc.WriteString("
    tags:  ")
    		desc.WriteString(categories)
    		desc.WriteString("
    comments: 1
    ")
    		desc.WriteString("---
    ")
    		tocIndex := strings.Index(item.Description, "[TOC]")
    		if tocIndex != -1 {
    			tocIndex += len("[TOC]")
    			desc.WriteString(item.Description[0:tocIndex])
    			desc.WriteString("
    [博客园原文地址 ")
    			desc.WriteString(item.Link)
    			desc.WriteString("](")
    			desc.WriteString(item.Link)
    			desc.WriteString(")
    
    ")
    			desc.WriteString(item.Description[tocIndex:])
    		} else {
    			desc.WriteString("
    [TOC]
    [博客园文章地址 ")
    			desc.WriteString(item.Link)
    			desc.WriteString("](")
    			desc.WriteString(item.Link)
    			desc.WriteString(")
    ")
    			desc.WriteString(item.Description)
    		}
    		err := ioutil.WriteFile(filename, desc.Bytes(), os.ModePerm)
    		if err != nil {
    			fmt.Println(err.Error())
    		}
    	}
    }
    
    
  • 相关阅读:
    convert.c:7:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by
    80 多个 Linux 系统管理员必备的监控工具
    控件风格19种,必须倒背如流——其实就是控件所拥有的能力,即有条件使用VCL框架所提供的(功能)代码
    控件状态11种,必须倒背如流——记录控件当前的状态,防止误判(一般使用完以后就把状态改回去)
    FindChildControl与FindComponent
    保存网页为图片——滚动截取IE(WebBrowse)
    HDOJ 1755
    IP编辑控件(因为封装的是系统自带控件,所以也使用了CreateSubClass,不过为啥要封装CN_COMMAND和CN_NOTIFY不是很明白)
    QT之深入理解QThread
    Qt读取ANSI格式文件——利用QTextCodec将其他编码格式的QByteArray转换为Unicode格式,或者从文件中读出后直接做转换
  • 原文地址:https://www.cnblogs.com/oloroso/p/11079838.html
Copyright © 2011-2022 走看看