0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ドコモメモ帳のバックアップをテキストファイルに変換するコードをGPTで作成

Posted at

経緯

今までdocomoのメモ帳を使っていましたが、ahamoへ切り替えた際に使えなくなりました。
なので、流行りののChat AIでメモをテキストファイルへ変換するRustプログラムを作成してみました。

最初の質問

以下のようにBEGIN:VEVENT, END:VEVENTで囲まれたものが複数あります。
それぞれのDESCRIPTIONとSUMMARYを抜き出しUnicode文字に変換するRust言語のコードを作成してください。

[docomoメモ帳のバックアップ(vcsファイル)の一部を抜き出して貼り付けしました]

最初の生成結果

まぁ最初はエラーになりますね。
ライフタイムが分かっていないのと、DESCRIPTIONが複数行の場合の対応ができていませんでした。
Rustが読みやすいからか修正の指示もしやすいですね。

use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Write};
use url::form_urlencoded;

fn main() -> io::Result<()> {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <file>", args[0]);
        return Ok(());
    }

    let file = File::open(&args[1])?;
    let reader = BufReader::new(file);

    let mut events = Vec::new();
    let mut event = HashMap::new();

    for line in reader.lines() {
        let line = line?;
        if line == "BEGIN:VEVENT" {
            event = HashMap::new();
        } else if line == "END:VEVENT" {
            events.push(event);
        } else {
            let parts: Vec<&str> = line.splitn(2, ':').collect();
            if parts.len() == 2 {
                let (key, value) = (parts[0], parts[1]);
                if key == "DESCRIPTION;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE" || key == "SUMMARY;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE" {
                    let decoded = form_urlencoded::parse(value.as_bytes())
                        .map(|(key, _)| key)
                        .collect::<String>();
                    event.insert(key.to_string(), decoded);
                }
            }
        }
    }

    for event in events {
        let description = event.get("DESCRIPTION;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE").unwrap_or(&"".to_string());
        let summary = event.get("SUMMARY;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE").unwrap_or(&"".to_string());

        let mut file = File::create(format!("{}.txt", summary))?;
        writeln!(file, "{}", description)?;
    }

    Ok(())
}

最終的な出力

いくつか修正指示を出して最終的には以下のようになりました。
まぁまぁ汚いですが短時間で目的は達成できたので良しとします。

以下で実行できます。
cargo run [vcsのファイルパス] [出力ディレクトリ]

use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::{self, BufRead, BufReader, Write};
use std::path::Path;
use url::form_urlencoded;

fn main() -> io::Result<()> {
    let args: Vec<String> = env::args().collect();
    if args.len() < 3 {
        println!("Usage: {} <file> <directory>", args[0]);
        return Ok(());
    }

    let file = File::open(&args[1])?;
    let reader = BufReader::new(file);
    let dir = &args[2];

    // Create the directory if it does not exist
    if !Path::new(dir).exists() {
        fs::create_dir_all(dir)?;
    }

    let mut events = Vec::new();
    let mut event = HashMap::new();
    let mut current_key = String::new();
    let mut current_value = String::new();
    let empty_string = "".to_string();

    for line in reader.lines() {
        let line = line?;
        if line == "BEGIN:VEVENT" {
            event.clear();
        } else if line == "END:VEVENT" {
            events.push(event.clone());
        } else if line.starts_with("DESCRIPTION;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE") || line.starts_with("SUMMARY;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE") {
            let parts: Vec<&str> = line.splitn(2, ':').collect();
            if parts.len() == 2 {
                let (key, value) = (parts[0], parts[1]);
                current_key = key.to_string();
                current_value = value.to_string();
            }
        } else if line.starts_with('=') {
            current_value.push_str(&line);
        } else {
            if !current_key.is_empty() {
                let decoded = form_urlencoded::parse(current_value.replace("=", "").as_bytes())
                    .map(|(key, _)| key)
                    .collect::<String>();
                let decoded_str = String::from_utf8(hex::decode(decoded).unwrap()).unwrap();
                event.insert(current_key.clone(), decoded_str);
                current_key.clear();
                current_value.clear();
            }
        }
    }

    for event in &events {
        let description = event.get("DESCRIPTION;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE").unwrap_or(&empty_string);
        let summary = event.get("SUMMARY;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE").unwrap_or(&empty_string);
        let summary = summary.replace("\n", "_");

        let mut file = File::create(format!("{}/{}.txt", dir, summary))?;
        writeln!(file, "{}", description)?;
    }

    Ok(())
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?