Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10494277
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Subscribers
None
View Options
diff --git a/api/api.go b/api/api.go
index 7d77a5b..3761658 100644
--- a/api/api.go
+++ b/api/api.go
@@ -1,304 +1,304 @@
package api
import (
"fmt"
"github.com/atotto/clipboard"
writeas "github.com/writeas/go-writeas/v2"
"github.com/writeas/web-core/posts"
"github.com/writeas/writeas-cli/config"
"github.com/writeas/writeas-cli/executable"
"github.com/writeas/writeas-cli/log"
cli "gopkg.in/urfave/cli.v1"
)
func HostURL(c *cli.Context) string {
host := c.GlobalString("host")
if host == "" {
return ""
}
insecure := c.Bool("insecure")
scheme := "https://"
if insecure {
scheme = "http://"
}
return scheme + host
}
func newClient(c *cli.Context) (*writeas.Client, error) {
var client *writeas.Client
var clientConfig writeas.Config
cfg, err := config.LoadConfig(config.UserDataDir(c.App.ExtraInfo()["configDir"]))
if err != nil {
return nil, fmt.Errorf("Failed to load configuration file: %v", err)
}
if host := HostURL(c); host != "" {
clientConfig.URL = host + "/api"
} else if cfg.Default.Host != "" && cfg.Default.User != "" {
clientConfig.URL = "https://" + cfg.Default.Host + "/api"
} else if config.IsDev() {
clientConfig.URL = config.DevBaseURL + "/api"
} else if c.App.Name == "writeas" {
clientConfig.URL = config.WriteasBaseURL + "/api"
} else {
return nil, fmt.Errorf("Must supply a host. Example: %s --host example.com %s", executable.Name(), c.Command.Name)
}
if config.IsTor(c) {
clientConfig.URL = config.TorURL(c)
clientConfig.TorPort = config.TorPort(c)
}
client = writeas.NewClientWith(clientConfig)
client.UserAgent = config.UserAgent(c)
return client, nil
}
// DoFetch retrieves the Write.as post with the given friendlyID,
// optionally via the Tor hidden service.
func DoFetch(c *cli.Context, friendlyID string) error {
cl, err := newClient(c)
if err != nil {
return err
}
p, err := cl.GetPost(friendlyID)
if err != nil {
return err
}
if p.Title != "" {
fmt.Printf("# %s\n\n", string(p.Title))
}
fmt.Printf("%s\n", string(p.Content))
return nil
}
// DoFetchPosts retrieves all remote posts for the
// authenticated user
func DoFetchPosts(c *cli.Context) ([]writeas.Post, error) {
cl, err := newClient(c)
if err != nil {
return nil, fmt.Errorf("%v", err)
}
u, _ := config.LoadUser(c)
if u != nil {
cl.SetToken(u.AccessToken)
} else {
return nil, fmt.Errorf("Not currently logged in. Authenticate with: " + executable.Name() + " auth <username>")
}
posts, err := cl.GetUserPosts()
if err != nil {
return nil, err
}
return *posts, nil
}
// DoPost creates a Write.as post, returning an error if it was
// unsuccessful.
func DoPost(c *cli.Context, post []byte, font string, encrypt, code bool) (*writeas.Post, error) {
cl, err := newClient(c)
if err != nil {
return nil, fmt.Errorf("%v", err)
}
u, _ := config.LoadUser(c)
- if u != nil && c.App.Name == "wf" {
+ if u != nil {
cl.SetToken(u.AccessToken)
} else {
return nil, fmt.Errorf("Not currently logged in. Authenticate with: " + executable.Name() + " auth <username>")
}
pp := &writeas.PostParams{
Font: config.GetFont(code, font),
Collection: config.Collection(c),
}
pp.Title, pp.Content = posts.ExtractTitle(string(post))
if lang := config.Language(c, true); lang != "" {
pp.Language = &lang
}
p, err := cl.CreatePost(pp)
if err != nil {
return nil, fmt.Errorf("Unable to post: %v", err)
}
cfg, err := config.LoadConfig(config.UserDataDir(c.App.ExtraInfo()["configDir"]))
if err != nil {
return nil, fmt.Errorf("Couldn't check for config file: %v", err)
}
var url string
if p.Collection != nil {
url = p.Collection.URL + p.Slug
} else {
if host := HostURL(c); host != "" {
url = host
} else if cfg.Default.Host != "" {
url = cfg.Default.Host
} else if config.IsDev() {
url = config.DevBaseURL
} else if config.IsTor(c) {
url = config.TorBaseURL
} else {
url = config.WriteasBaseURL
}
url += "/" + p.ID
// Output URL in requested format
if c.Bool("md") {
url += ".md"
}
}
if cl.Token() == "" {
// Store post locally, since we're not authenticated
AddPost(c, p.ID, p.Token)
}
// Copy URL to clipboard
err = clipboard.WriteAll(string(url))
if err != nil {
log.Errorln(executable.Name()+": Didn't copy to clipboard: %s", err)
} else {
log.Info(c, "Copied to clipboard.")
}
// Output URL
fmt.Printf("%s\n", url)
return p, nil
}
// DoFetchCollections retrieves a list of the currently logged in users
// collections.
func DoFetchCollections(c *cli.Context) ([]RemoteColl, error) {
cl, err := newClient(c)
if err != nil {
if config.Debug() {
log.ErrorlnQuit("could not create client: %v", err)
}
return nil, fmt.Errorf("Couldn't create new client")
}
u, _ := config.LoadUser(c)
if u != nil {
cl.SetToken(u.AccessToken)
} else {
return nil, fmt.Errorf("Not currently logged in. Authenticate with: " + executable.Name() + " auth <username>")
}
colls, err := cl.GetUserCollections()
if err != nil {
if config.Debug() {
log.ErrorlnQuit("failed fetching user collections: %v", err)
}
return nil, fmt.Errorf("Couldn't get user blogs")
}
out := make([]RemoteColl, len(*colls))
for i, c := range *colls {
coll := RemoteColl{
Alias: c.Alias,
Title: c.Title,
URL: c.URL,
}
out[i] = coll
}
return out, nil
}
// DoUpdate updates the given post on Write.as.
func DoUpdate(c *cli.Context, post []byte, friendlyID, token, font string, code bool) error {
cl, err := newClient(c)
if err != nil {
return fmt.Errorf("%v", err)
}
params := writeas.PostParams{}
params.Title, params.Content = posts.ExtractTitle(string(post))
if lang := config.Language(c, false); lang != "" {
params.Language = &lang
}
if code || font != "" {
params.Font = config.GetFont(code, font)
}
_, err = cl.UpdatePost(friendlyID, token, ¶ms)
if err != nil {
if config.Debug() {
log.ErrorlnQuit("Problem updating: %v", err)
}
return fmt.Errorf("Post doesn't exist, or bad edit token given.")
}
return nil
}
// DoDelete deletes the given post on Write.as, and removes any local references
func DoDelete(c *cli.Context, friendlyID, token string) error {
cl, err := newClient(c)
if err != nil {
return fmt.Errorf("%v", err)
}
err = cl.DeletePost(friendlyID, token)
if err != nil {
if config.Debug() {
log.ErrorlnQuit("Problem deleting: %v", err)
}
return fmt.Errorf("Post doesn't exist, or bad edit token given.")
}
RemovePost(c, friendlyID)
return nil
}
func DoLogIn(c *cli.Context, username, password string) error {
cl, err := newClient(c)
if err != nil {
return fmt.Errorf("%v", err)
}
u, err := cl.LogIn(username, password)
if err != nil {
if config.Debug() {
log.ErrorlnQuit("Problem logging in: %v", err)
}
return err
}
err = config.SaveUser(c, u)
if err != nil {
return err
}
log.Info(c, "Logged in as %s.\n", u.User.Username)
return nil
}
func DoLogOut(c *cli.Context) error {
cl, err := newClient(c)
if err != nil {
return fmt.Errorf("%v", err)
}
u, _ := config.LoadUser(c)
if u != nil {
cl.SetToken(u.AccessToken)
} else if c.App.Name == "writeas" {
return fmt.Errorf("Not currently logged in. Authenticate with: " + executable.Name() + " auth <username>")
}
err = cl.LogOut()
if err != nil {
if config.Debug() {
log.ErrorlnQuit("Problem logging out: %v", err)
}
return err
}
// delete local user file
return config.DeleteUser(c)
}
diff --git a/config/user.go b/config/user.go
index 45c287d..f39cb73 100644
--- a/config/user.go
+++ b/config/user.go
@@ -1,169 +1,172 @@
package config
import (
"encoding/json"
"io/ioutil"
"path/filepath"
writeas "github.com/writeas/go-writeas/v2"
"github.com/writeas/writeas-cli/fileutils"
"gopkg.in/urfave/cli.v1"
)
func LoadUser(c *cli.Context) (*writeas.AuthUser, error) {
dir, err := UserHostDir(c)
if err != nil {
return nil, err
}
DirMustExist(dir)
username, err := CurrentUser(c)
if err != nil {
return nil, err
}
if username == "user" {
username = ""
}
fname := filepath.Join(dir, username, "user.json")
userJSON, err := ioutil.ReadFile(fname)
if err != nil {
if !fileutils.Exists(fname) {
// Don't return a file-not-found error
return nil, nil
}
return nil, err
}
// Parse JSON file
u := &writeas.AuthUser{}
err = json.Unmarshal(userJSON, u)
if err != nil {
return nil, err
}
return u, nil
}
func DeleteUser(c *cli.Context) error {
dir, err := UserHostDir(c)
if err != nil {
return err
}
username, err := CurrentUser(c)
if err != nil {
return err
}
if username == "user" {
username = ""
}
// Delete user data
err = fileutils.DeleteFile(filepath.Join(dir, username, "user.json"))
if err != nil {
return err
}
// Do additional cleanup in wf-cli
if c.App.Name == "wf" {
// Delete user dir if it's empty
userEmpty, err := fileutils.IsEmpty(filepath.Join(dir, username))
if err != nil {
return err
}
if !userEmpty {
return nil
}
err = fileutils.DeleteFile(filepath.Join(dir, username))
if err != nil {
return err
}
// Delete host dir if it's empty
hostEmpty, err := fileutils.IsEmpty(dir)
if err != nil {
return err
}
if !hostEmpty {
return nil
}
err = fileutils.DeleteFile(dir)
if err != nil {
return err
}
}
return nil
}
func SaveUser(c *cli.Context, u *writeas.AuthUser) error {
// Marshal struct into pretty-printed JSON
userJSON, err := json.MarshalIndent(u, "", " ")
if err != nil {
return err
}
dir, err := UserHostDir(c)
if err != nil {
return err
}
// Save file
username, err := CurrentUser(c)
if err != nil {
return err
}
if username != "user" {
dir = filepath.Join(dir, u.User.Username)
}
DirMustExist(dir)
err = ioutil.WriteFile(filepath.Join(dir, "user.json"), userJSON, 0600)
if err != nil {
return err
}
return nil
}
// UserHostDir returns the path to the user data directory with the host based
// subpath if the host flag is set
func UserHostDir(c *cli.Context) (string, error) {
dataDir := UserDataDir(c.App.ExtraInfo()["configDir"])
hostDir, err := HostDirectory(c)
if err != nil {
return "", err
}
return filepath.Join(dataDir, hostDir), nil
}
// CurrentUser returns the username of the user taking action in the current
// cli.Context.
func CurrentUser(c *cli.Context) (string, error) {
+ if c.App.Name == "writeas" {
+ return "user", nil
+ }
// Use user flag value
if c.GlobalString("user") != "" {
return c.GlobalString("user"), nil
}
// Load host-level config, if host flag is set
hostDir, err := UserHostDir(c)
if err != nil {
return "", err
}
cfg, err := LoadConfig(hostDir)
if err != nil {
return "", err
}
if cfg.Default.User == "" {
// Load app-level config
globalCFG, err := LoadConfig(UserDataDir(c.App.ExtraInfo()["configDir"]))
if err != nil {
return "", err
}
// only user global defaults when both are set and hosts match
if globalCFG.Default.User != "" &&
globalCFG.Default.Host != "" &&
c.GlobalIsSet("host") &&
globalCFG.Default.Host == c.GlobalString("host") {
cfg = globalCFG
}
}
return cfg.Default.User, nil
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Mar 6, 10:41 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3166725
Attached To
rWCLI writeas-cli
Event Timeline
Log In to Comment