diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ebfde9a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true, +} \ No newline at end of file diff --git a/cmd/kiss-cli/main.go b/cmd/kiss-cli/main.go new file mode 100644 index 0000000..79c17e0 --- /dev/null +++ b/cmd/kiss-cli/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "h4kor/kiss-social" + "os" +) + +func main() { + println("KISS Social") + println("Commands") + println("new - Creates a new user") + + args := os.Args[1:] + if len(args) == 0 { + println("No command given") + return + } + + switch args[0] { + case "new": + if len(args) != 2 { + println("Invalid number of arguments") + return + } + kiss.CreateNewUser("users", args[1]) + default: + println("Invalid command") + } +} diff --git a/kiss-cli b/kiss-cli new file mode 100755 index 0000000..0fcc341 Binary files /dev/null and b/kiss-cli differ diff --git a/main.go b/main.go deleted file mode 100644 index e5f91bb..0000000 --- a/main.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "os" - "path" - "time" - "fmt" -) - -func CreateNewUser(repo string, name string) { - // creates repo folder if it doesn't exist - os.Mkdir(repo, 0755) - - // creates repo/name folder if it doesn't exist - user_dir := path.Join(repo, name) - os.Mkdir(user_dir, 0755) - os.Mkdir(path.Join(user_dir, "meta"), 0755) - // create public folder - os.Mkdir(path.Join(user_dir, "public"), 0755) - - // create Meta files - os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte("0.0.1"), 0644) - os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte("<{{content}}/body>"), 0644) -} - -func CreateNewPost(repo string, user string, title string) { - timestamp := time.Now().UTC().Unix() - folder_name := fmt.Sprintf("%d-%s", timestamp, title) - post_dir := path.Join(repo, user, "public", folder_name) - - // if post already exists, add -n to the end of the name - i := 0 - for { - if _, err := os.Stat(post_dir); err == nil { - i++ - folder_name = fmt.Sprintf("%d-%s-%d", timestamp, title, i) - post_dir = path.Join(repo, user, "public", folder_name) - } else { - break - } - } - - initial_content := "# " + title - // create post file - os.Mkdir(post_dir, 0755) - os.WriteFile(path.Join(post_dir, "index.md"), []byte(initial_content), 0644) -} - -func main() { - println("KISS Social") - println("Commands") - println("new - Creates a new user") - - args := os.Args[1:] - if len(args) == 0 { - println("No command given") - return - } - - switch args[0] { - case "new": - if len(args) != 2 { - println("Invalid number of arguments") - return - } - CreateNewUser("users", args[1]) - default: - println("Invalid command") - } -} \ No newline at end of file diff --git a/main_test.go b/main_test.go deleted file mode 100644 index a4379df..0000000 --- a/main_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package main_test - -import ( - "testing" - "os" - "fmt" - "path" - "time" - "io/ioutil" - "math/rand" - "h4kor/kiss-social" -) - - -func testRepo() string { - return "/tmp/test" -} - -func randomUserName() string { - rand.Seed(time.Now().UnixNano()) - var letters = []rune("abcdefghijklmnopqrstuvwxyz") - b := make([]rune, 8) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - return string(b) -} - -func TestCanCreateANewUser(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - if _, err := os.Stat(path.Join(repo, user, "")); err != nil { - t.Error("User directory not created") - } -} - -func TestCreateUserAddsVersionFile(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - if _, err := os.Stat(path.Join(repo, user, "/meta/VERSION")); err != nil { - t.Error("Version file not created") - } -} - -func TestCreateUserAddsBaseHtmlFile(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - if _, err := os.Stat(path.Join(repo, user, "/meta/base.html")); err != nil { - t.Error("Base html file not created") - } -} - -func TestCreateUserAddsPublicFolder(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - if _, err := os.Stat(path.Join(repo, user, "/public")); err != nil { - t.Error("Public folder not created") - } -} - -func TestCreateNewPostCreatesEntryInPublic(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - // Create a new post - main.CreateNewPost(repo, user, "testpost") - files, err := ioutil.ReadDir(path.Join(repo, user, "public")) - if err != nil { - t.Error("Error reading directory") - } - if len(files) < 1 { - t.Error("Post not created") - } -} - -func TestCreateNewPostMultipleCalls(t *testing.T) { - // Create a new user - repo := testRepo() - user := randomUserName() - main.CreateNewUser(repo, user) - // Create a new post - main.CreateNewPost(repo, user, "testpost") - main.CreateNewPost(repo, user, "testpost") - main.CreateNewPost(repo, user, "testpost") - files, err := ioutil.ReadDir(path.Join(repo, user, "public")) - if err != nil { - t.Error("Error reading directory") - } - if len(files) < 3 { - t.Error(fmt.Sprintf("Only %d posts created", len(files))) - } -} \ No newline at end of file diff --git a/repository.go b/repository.go new file mode 100644 index 0000000..683a6ad --- /dev/null +++ b/repository.go @@ -0,0 +1,88 @@ +package kiss + +import ( + "fmt" + "os" + "path" + "time" +) + +type Repository struct { + name string +} + +type User struct { + repo Repository + name string +} + +type Post struct { + user User + title string +} + +func CreateRepository(name string) (Repository, error) { + // check if repository already exists + if _, err := os.Stat(name); err == nil { + return Repository{}, fmt.Errorf("Repository already exists") + } + + os.Mkdir(name, 0755) + return Repository{name: name}, nil +} + +func (repo Repository) Dir() string { + return repo.name +} + +func (user User) Dir() string { + return path.Join(user.repo.Dir(), user.name) +} + +func PostDir(post Post) string { + return path.Join(post.user.Dir(), "public", post.title) +} + +func CreateNewUser(repo Repository, name string) (User, error) { + new_user := User{repo: repo, name: name} + // check if user already exists + if _, err := os.Stat(new_user.Dir()); err == nil { + return User{}, fmt.Errorf("User already exists") + } + + // creates repo/name folder if it doesn't exist + user_dir := new_user.Dir() + os.Mkdir(user_dir, 0755) + os.Mkdir(path.Join(user_dir, "meta"), 0755) + // create public folder + os.Mkdir(path.Join(user_dir, "public"), 0755) + + // create Meta files + os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte("0.0.1"), 0644) + os.WriteFile(path.Join(user_dir, "meta", "base.html"), []byte("<{{content}}/body>"), 0644) + + return new_user, nil +} + +func CreateNewPost(user User, title string) { + timestamp := time.Now().UTC().Unix() + folder_name := fmt.Sprintf("%d-%s", timestamp, title) + post_dir := path.Join(user.Dir(), "public", folder_name) + + // if post already exists, add -n to the end of the name + i := 0 + for { + if _, err := os.Stat(post_dir); err == nil { + i++ + folder_name = fmt.Sprintf("%d-%s-%d", timestamp, title, i) + post_dir = path.Join(user.Dir(), "public", folder_name) + } else { + break + } + } + + initial_content := "# " + title + // create post file + os.Mkdir(post_dir, 0755) + os.WriteFile(path.Join(post_dir, "index.md"), []byte(initial_content), 0644) +} diff --git a/repository_test.go b/repository_test.go new file mode 100644 index 0000000..e7e39bd --- /dev/null +++ b/repository_test.go @@ -0,0 +1,127 @@ +package kiss_test + +import ( + "fmt" + "h4kor/kiss-social" + "io/ioutil" + "math/rand" + "os" + "path" + "testing" + "time" +) + +func randomName() string { + rand.Seed(time.Now().UnixNano()) + var letters = []rune("abcdefghijklmnopqrstuvwxyz") + b := make([]rune, 8) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} + +func testRepoName() string { + return "/tmp/" + randomName() +} + +func randomUserName() string { + return randomName() +} + +func TestCanCreateRepository(t *testing.T) { + repoName := testRepoName() + _, err := kiss.CreateRepository(repoName) + if err != nil { + t.Error("Error creating repository: ", err) + } + +} + +func TestCannotCreateExistingRepository(t *testing.T) { + repoName := testRepoName() + kiss.CreateRepository(repoName) + _, err := kiss.CreateRepository(repoName) + if err == nil { + t.Error("No error returned when creating existing repository") + } +} + +func TestCanCreateANewUser(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + if _, err := os.Stat(path.Join(user.Dir(), "")); err != nil { + t.Error("User directory not created") + } +} + +func TestCannotRecreateExisitingUser(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + userName := randomUserName() + kiss.CreateNewUser(repo, userName) + _, err := kiss.CreateNewUser(repo, userName) + if err == nil { + t.Error("No error returned when creating existing user") + } +} + +func TestCreateUserAddsVersionFile(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + if _, err := os.Stat(path.Join(user.Dir(), "/meta/VERSION")); err != nil { + t.Error("Version file not created") + } +} + +func TestCreateUserAddsBaseHtmlFile(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + if _, err := os.Stat(path.Join(user.Dir(), "/meta/base.html")); err != nil { + t.Error("Base html file not created") + } +} + +func TestCreateUserAddsPublicFolder(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + if _, err := os.Stat(path.Join(user.Dir(), "/public")); err != nil { + t.Error("Public folder not created") + } +} + +func TestCreateNewPostCreatesEntryInPublic(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + // Create a new post + kiss.CreateNewPost(user, "testpost") + files, err := ioutil.ReadDir(path.Join(user.Dir(), "public")) + if err != nil { + t.Error("Error reading directory") + } + if len(files) < 1 { + t.Error("Post not created") + } +} + +func TestCreateNewPostMultipleCalls(t *testing.T) { + // Create a new user + repo, _ := kiss.CreateRepository(testRepoName()) + user, _ := kiss.CreateNewUser(repo, randomUserName()) + // Create a new post + kiss.CreateNewPost(user, "testpost") + kiss.CreateNewPost(user, "testpost") + kiss.CreateNewPost(user, "testpost") + files, err := ioutil.ReadDir(path.Join(user.Dir(), "public")) + if err != nil { + t.Error("Error reading directory") + } + if len(files) < 3 { + t.Error(fmt.Sprintf("Only %d posts created", len(files))) + } +}