about summary refs log tree commit diff stats
path: root/config.mk
blob: d3a6ffd9792b7f0827aafc7173b9d93c6635a1dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# dwm version
VERSION = 3.6

# Customize below to fit your system

# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man

X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib

# includes and libs
INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11

# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}

# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
#CFLAGS += -xtarget=ultra

# compiler and linker
CC = cc
gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
use std::io;

use crate::db;
use crate::error;
use crate::user;

#[cfg(not(test))]
use crate::ed;

// Make sure nobody encodes narsty characters
// into a message to negatively affect other
// users
fn str_to_utf8(str: &str) -> String {
    str.chars()
        .map(|c| {
            let mut buf = [0; 4];
            c.encode_utf8(&mut buf).to_string()
        })
        .collect::<String>()
}

// First handler for creating a new post.
pub fn create() -> error::Result<()> {
    println!();
    println!("Title of the new post: ");

    #[cfg(test)]
    let title = String::from("TEST_TITLE");

    #[cfg(not(test))]
    let mut title = String::new();

    #[cfg(not(test))]
    io::stdin().read_line(&mut title)?;

    let title = str_to_utf8(title.trim());
    let title = if title.len() > 30 {
        &title[..30]
    } else {
        &title
    };

    println!();

    #[cfg(not(test))]
    let body_raw = str_to_utf8(&ed::call(""));

    #[cfg(not(test))]
    let body = if body_raw.len() > 500 {
        &body_raw[..500]
    } else {
        &body_raw
    };

    #[cfg(test)]
    let body = String::from("TEST_BODY");

    let trimmed_body = body.trim();
    let user = &*user::NAME;

    let mut all = db::Posts::get_all(db::PATH);
    let new = db::Post {
        author: user.into(),
        title: title.to_string(),
        body: trimmed_body.to_string(),
    };

    all.append(new);
    all.write();

    println!();
    Ok(())
}

// Shows the most recent posts.
pub fn display() -> error::Result<()> {
    let all = db::Posts::get_all(db::PATH);

    let mut postvec = Vec::new();
    all.posts().iter().enumerate().for_each(|(id, post)| {
        let newpost = format!(
            "{}. {} -> by {}\n{}\n\n",
            id + 1,
            post.title.trim(),
            post.author,
            post.body.trim()
        );
        postvec.push(newpost);
    });

    for (i, e) in postvec.iter().enumerate() {
        if (postvec.len() > 14 && i >= postvec.len() - 15) || postvec.len() < 15 {
            print!("{}", e);
        }
    }

    Ok(())
}

// First handler to update posts.
pub fn update_handler(id: usize) -> error::Result<()> {
    let mut id_num_in = if id == 0 {
        println!();
        println!("ID number of your post to edit?");
        let mut id_num_in = String::new();
        io::stdin().read_line(&mut id_num_in)?;
        id_num_in.trim().parse()?
    } else {
        id
    };

    id_num_in -= 1;

    #[cfg(not(test))]
    let user = &*user::NAME;

    let mut all = db::Posts::get_all(db::PATH);
    let post = all.get(id_num_in);

    #[cfg(test)]
    let user = &post.author;

    if *user != post.author {
        println!();
        println!("Users don't match. Can't update post!");
        println!();
        std::process::exit(1);
    }

    #[cfg(test)]
    let new_title = String::from("TEST_TITLE");

    #[cfg(not(test))]
    let mut new_title = String::new();

    println!("Updating post {}", id_num_in);
    println!();
    println!("Current Title: {}", post.title);
    println!();
    println!("Enter new title:");

    #[cfg(not(test))]
    io::stdin().read_line(&mut new_title)?;

    #[cfg(test)]
    let body_raw = String::from("TEST_BODY");

    #[cfg(not(test))]
    let body_raw = str_to_utf8(&ed::call(&post.body));

    let body = if body_raw.len() > 500 {
        &body_raw[..500]
    } else {
        &body_raw
    };

    let trimmed_body = body.trim();

    all.replace(
        id_num_in,
        db::Post {
            author: user.into(),
            title: new_title,
            body: trimmed_body.to_string(),
        },
    );

    all.write();

    println!();
    Ok(())
}

// First handler to remove a post
pub fn delete_handler(id: usize) -> error::Result<()> {
    let mut id_num_in = if id == 0 {
        println!();
        println!("ID of the post to delete?");
        let mut id_num_in = String::new();
        io::stdin().read_line(&mut id_num_in)?;
        println!();
        id_num_in.trim().parse()?
    } else {
        id
    };

    id_num_in -= 1;

    let mut all = db::Posts::get_all(db::PATH);
    let post = all.get(id_num_in);

    if *user::NAME != post.author {
        println!();
        println!("Users don't match. Can't delete post!");
        println!();
        std::process::exit(1);
    }

    all.delete(id_num_in);
    all.write();

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::fs;

    #[test]
    fn test_str_to_utf8() {
        let lhs = "foobar";
        let rhs = str_to_utf8(lhs);
        assert_eq!(lhs, rhs);
    }

    #[test]
    fn display_doesnt_explode() {
        assert!(display().is_ok());
    }

    #[test]
    fn test_update_handler() {
        fs::copy(db::PATH, "clinte_bak.json").unwrap();
        update_handler(1).unwrap();
        let all = db::Posts::get_all(db::PATH);
        let post = all.get(0);
        assert_eq!(post.title, "TEST_TITLE");
        assert_eq!(post.body, "TEST_BODY");
        fs::rename("clinte_bak.json", db::PATH).unwrap();
    }

    #[test]
    fn test_create_delete() {
        fs::copy(db::PATH, "clinte_bak.json").unwrap();
        create().unwrap();
        let all = db::Posts::get_all(db::PATH);
        let post = all.get(1);

        assert_eq!(post.title, "TEST_TITLE");
        assert_eq!(post.body, "TEST_BODY");

        delete_handler(2).unwrap();

        fs::rename("clinte_bak.json", db::PATH).unwrap();
    }
}