Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10528770
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Subscribers
None
View Options
diff --git a/api/api.go b/api/api.go
index 31e90e7..b60d9c1 100644
--- a/api/api.go
+++ b/api/api.go
@@ -1,268 +1,281 @@
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, authRequired bool) (*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 c.GlobalString("host") != "" {
- clientConfig.URL = c.GlobalString("host") + "/api"
+ if host := HostURL(c); host != "" {
+ clientConfig.URL = host + "/api"
} else if cfg.Default.Host != "" {
clientConfig.URL = cfg.Default.Host + "/api"
} else if config.IsDev() {
clientConfig.URL = config.DevBaseURL + "/api"
} else {
clientConfig.URL = config.WriteasBaseURL + "/api"
}
if config.IsTor(c) {
clientConfig.URL = config.TorURL(c)
clientConfig.TorPort = config.TorPort(c)
}
client = writeas.NewClientWith(clientConfig)
client.UserAgent = config.UserAgent(c)
// TODO: load user into var shared across the app
u, _ := config.LoadUser(c)
if u != nil {
client.SetToken(u.AccessToken)
} else if authRequired {
return nil, fmt.Errorf("Not currently logged in. Authenticate with: " + executable.Name() + " auth <username>")
}
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, false)
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, true)
if err != nil {
return nil, fmt.Errorf("%v", err)
}
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, false)
if err != nil {
return nil, fmt.Errorf("%v", err)
}
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 c.GlobalString("host") != "" {
url = c.GlobalString("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, true)
if err != nil {
if config.Debug() {
log.ErrorlnQuit("could not create client: %v", err)
}
return nil, fmt.Errorf("Couldn't create new client")
}
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, false)
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, false)
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, false)
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, true)
if err != nil {
return fmt.Errorf("%v", err)
}
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/flags.go b/config/flags.go
index 2c17e23..195eb8d 100644
--- a/config/flags.go
+++ b/config/flags.go
@@ -1,50 +1,54 @@
package config
import (
"gopkg.in/urfave/cli.v1"
)
// Available flags for creating posts
var PostFlags = []cli.Flag{
cli.StringFlag{
Name: "c, b",
Usage: "Optional blog to post to",
Value: "",
},
+ cli.BoolFlag{
+ Name: "insecure",
+ Usage: "Send request insecurely.",
+ },
cli.BoolFlag{
Name: "tor, t",
Usage: "Perform action on Tor hidden service",
},
cli.IntFlag{
Name: "tor-port",
Usage: "Use a different port to connect to Tor",
Value: 9150,
},
cli.BoolFlag{
Name: "code",
Usage: "Specifies this post is code",
},
cli.BoolFlag{
Name: "md",
Usage: "Returns post URL with Markdown enabled",
},
cli.BoolFlag{
Name: "verbose, v",
Usage: "Make the operation more talkative",
},
cli.StringFlag{
Name: "font",
Usage: "Sets post font to given value",
Value: DefaultFont,
},
cli.StringFlag{
Name: "lang",
Usage: "Sets post language to given ISO 639-1 language code",
Value: "",
},
cli.StringFlag{
Name: "user-agent",
Usage: "Sets the User-Agent for API requests",
Value: "",
},
}
diff --git a/config/options.go b/config/options.go
index 047c5c4..adbed78 100644
--- a/config/options.go
+++ b/config/options.go
@@ -1,105 +1,101 @@
package config
import (
"net/url"
"strings"
"github.com/cloudfoundry/jibber_jabber"
"github.com/writeas/writeas-cli/log"
cli "gopkg.in/urfave/cli.v1"
)
// Application constants.
const (
defaultUserAgent = "writeas-cli v"
// Defaults for posts on Write.as.
DefaultFont = PostFontMono
WriteasBaseURL = "https://write.as"
DevBaseURL = "https://development.write.as"
TorBaseURL = "http://writeas7pm7rcdqg.onion"
torPort = 9150
)
func UserAgent(c *cli.Context) string {
ua := c.String("user-agent")
if ua == "" {
return defaultUserAgent + c.App.ExtraInfo()["version"]
}
return ua + " (" + defaultUserAgent + c.App.ExtraInfo()["version"] + ")"
}
func IsTor(c *cli.Context) bool {
return c.Bool("tor") || c.Bool("t")
}
func TorPort(c *cli.Context) int {
if c.IsSet("tor-port") && c.Int("tor-port") != 0 {
return c.Int("tor-port")
}
return torPort
}
func TorURL(c *cli.Context) string {
flagHost := c.String("host")
if flagHost != "" && strings.HasSuffix(flagHost, "onion") {
return flagHost
}
cfg, _ := LoadConfig(c.App.ExtraInfo()["configDir"])
if cfg != nil && cfg.Default.Host != "" && strings.HasSuffix(cfg.Default.Host, "onion") {
return cfg.Default.Host
}
return TorBaseURL
}
func Language(c *cli.Context, auto bool) string {
if l := c.String("lang"); l != "" {
return l
}
if !auto {
return ""
}
// Automatically detect language
l, err := jibber_jabber.DetectLanguage()
if err != nil {
log.Info(c, "Language detection failed: %s", err)
return ""
}
return l
}
func Collection(c *cli.Context) string {
if coll := c.String("c"); coll != "" {
return coll
}
if coll := c.String("b"); coll != "" {
return coll
}
u, _ := LoadUser(c)
if u != nil {
return u.User.Username
}
return ""
}
// HostDirectory returns the sub directory string for the host. Order of
// precedence is a host flag if any, then the configured default, if any
func HostDirectory(c *cli.Context) (string, error) {
cfg, err := LoadConfig(UserDataDir(c.App.ExtraInfo()["configDir"]))
if err != nil {
return "", err
}
// flag takes precedence over defaults
if hostFlag := c.GlobalString("host"); hostFlag != "" {
- u, err := url.Parse(hostFlag)
- if err != nil {
- return "", err
- }
- return u.Hostname(), nil
+ return hostFlag, nil
}
u, err := url.Parse(cfg.Default.Host)
if err != nil {
return "", err
}
return u.Hostname(), nil
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Apr 6, 3:05 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3188751
Attached To
rWCLI writeas-cli
Event Timeline
Log In to Comment