Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Implement actual post creation through the REST API as documented in part 6 of the series. Also change to Lua-cURL (a binary is in this checkin) and add a bunch of commandline options. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
a6505fd2e2eaa9212dcf02f40a54411f |
| User & Date: | Ross 2014-10-14 00:28:56.266 |
Context
|
2014-10-14
| ||
| 00:56 | Cosmetic change that could have been published but wasn't (yet). check-in: 5a94554cc9 user: Ross tags: trunk | |
| 00:28 | Implement actual post creation through the REST API as documented in part 6 of the series. Also change to Lua-cURL (a binary is in this checkin) and add a bunch of commandline options. check-in: a6505fd2e2 user: Ross tags: trunk | |
|
2014-10-03
| ||
| 22:33 | Implement --tokenurl parsing and track token expiration. Add json parser and provide a simple display of the user name attached to the token for the --verbose option. Clean up --verbose output by adding the --debug option to cover most of the noisy printing. check-in: 870da6391b user: Ross tags: trunk | |
Changes
Added wprest/cURL.dll.
cannot compute difference between binary files
Added wprest/liblua.dll.
cannot compute difference between binary files
Changes to wprest/wppost.lua.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | -- the terms of the MIT license. See readme.markdown for details. local utils = require "pl.utils" local app = require "pl.app" local lapp = require "pl.lapp" local config = require "pl.config" local pretty = require "pl.pretty" | < > > > > > | | > > < > > > > | > > > > > > > > > > > > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
-- the terms of the MIT license. See readme.markdown for details.
local utils = require "pl.utils"
local app = require "pl.app"
local lapp = require "pl.lapp"
local config = require "pl.config"
local pretty = require "pl.pretty"
local json = require "json"
local cURL = require "cURL"
-- Put the pl.lapp based options handling near the top for easy visibility
local args = lapp [[
Post a file on a WordPres blog as a draft post. Part of the WP CLI Tools.
http://curiouser.cheshireeng.com/applications/wp-cli-tools/
These options are related to the config file, with the ones marked * actually
stored in the file. Either --blog or --site and --token must be available and
consistent for posting to be allowed.
--blog (default "") *The blog at which to post.
--token (default "") *The OAuth token from the redirect URL.
--expires (default "") *The OAuth token expiration date.
--site (default "") *The WP Site ID for the token's blog.
--tokenurl (default "") The full URL containing the token
--showconfig Just display the config file
--writeconfig Write the config file with the options
General options:
-v,--verbose Be more chatty about the process
--keepraw (default "") Name a file to fill with raw logging
--debug Don't use this
Options for the blog post itself:
--title (default "") The post title. Defaults to the file name.
--tags (default "") Comma separated list of tags to apply.
--category (default "") Comma separated list of categories to apply.
<filename> (default "") The file to post.
]]
-- erase some optional fields from the args table completely
for _,k in ipairs{'title','tags','category','keepraw'} do
if args[k] and (#args[k] < 1) then args[k] = nil end
end
-- get the raw debug log open if wanted
if args.keepraw then
args.keepraw_name = args.keepraw
args.keepraw = io.open(args.keepraw, "wb")
end
-- Also read a config file stored in a "home directory" folder
local configfile = app.appfile"rest.ini"
if args.showconfig then
print("config:", configfile)
local s = utils.readfile(configfile)
io.write(s or "--config file empty--\n")
end
local conf = config.read(configfile) or {
blog = "curiouser.cheshireeng.com",
site = "73256621",
token= 'X'
}
-- Parse the useful data out of a token redirect URL
-- Keep the token, confirm the other details.
--
-- http://<URL>/#access_token=<URL-Encoded-Token>&expires_in=<seconds>&token_type=bearer&site_id=73256621
|
| ︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
local t={}
for k,v in rest:gmatch"([^&=]+)=([^&=]+)" do
t[k] = v
if args.debug then print("URL",k,v) end
end
args.token = t.access_token
args.expires = tostring(os.time() + (tonumber(t.expires_in) or 0))
end
end
-- Add missing configuration fields to args
for k,v in pairs(conf) do
if (not args[k]) or (#args[k] < 1) then args[k] = v end
end
-- Possibly write back the config file
if args.writeconfig then
local f = io.open(configfile, "w")
f:write"# configuration written by the --writeconfig option\n\n"
| > | | | > > > > | > | | | | < | > > | > > > > > > > | < | | | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
local t={}
for k,v in rest:gmatch"([^&=]+)=([^&=]+)" do
t[k] = v
if args.debug then print("URL",k,v) end
end
args.token = t.access_token
args.expires = tostring(os.time() + (tonumber(t.expires_in) or 0))
args.site = t.site_id
end
end
-- Add missing configuration fields to args
for k,v in pairs(conf) do
if (not args[k]) or (#args[k] < 1) then args[k] = v end
end
-- Possibly write back the config file
if args.writeconfig then
local f = io.open(configfile, "w")
f:write"# configuration written by the --writeconfig option\n\n"
for _,k in ipairs({"blog","token","expires","site"}) do
f:write(k,"=",args[k],"\n")
end
f:close()
end
args.token = cURL.unescape(args.token)
if args.debug then
print("unescaped token ("..#args.token.." bytes):", ("%q"):format(args.token))
end
if #args.token ~= 64 then
lapp.error("WP Access Token must be exactly 64 bytes long.", false)
end
args.expires = tonumber(args.expires)
if args.expires then
local ttl = (args.expires - os.time()) / (24. * 3600.)
if ttl < 0 then
print(("WP Access Token expired %.1f days ago"):format(-ttl))
else
print(("WP Access Token expires in %.1f days"):format(ttl))
end
end
args.baseurl = "https://public-api.wordpress.com/rest/v1/sites/"
.. (args.site or args.blog)
if args.debug then print(pretty.write(args)) end
-- Discover information about the user attached to the token,
-- return it as a table decoded from the JSON data.
function wp_showme()
--$access_key = "YOUR_API_TOKEN";
local c = cURL.easy_init()
c:setopt_url "https://public-api.wordpress.com/rest/v1/me/"
c:setopt_httpheader('Authorization: Bearer ' .. args.token)
c:setopt_ssl_verifypeer(0)
local t,h = {},{}
c:perform{
writefunction = function(s)
t[#t+1] = s
end,
headerfunction = function(s)
h[#h+1] = s
end,
}
c = nil
-- print("headers=",pretty.write(h))
local j = json.decode(table.concat(t))
return j
end
if args.verbose then
local me = wp_showme()
if args.debug then
io.write("/me = ", pretty.write(me), '\n')
--io.write("/me = ", wp_showme())
end
print("Token user:", me.display_name or me.username)
if me.email_verified then
print(" email:", me.email or "unknown")
end
end
-- exit before actually doing anything if requested.
if args.showconfig or args.writeconfig then os.exit(0) end
-- verify if we got this far that we really do have a file to process
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 | return e end --- -- Make a new post on a WordPress blog found at args.baseurl, using the OAuth -- token with the given title and body. The new post is always a draft and -- will have no Tags and the default Category. | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > | | | < > | | > > > > | > | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
return e
end
---
-- Make a new post on a WordPress blog found at args.baseurl, using the OAuth
-- token with the given title and body. The new post is always a draft and
-- will have no Tags and the default Category.
local function wp_newPost(title, body, category, tags, options)
options = options or {}
local c = cURL.easy_init()
local url = args.baseurl..[[/posts/new?context=edit&http_envelope=true]]
if args.verbose then print (url) end
c:setopt_url(url)
c:setopt_httpheader('Authorization: Bearer ' .. args.token)
c:post{
status = options.status or "draft",
categories = category or "Experiments",
tags = tags,
type = "post",
title = htmlentities(title),
content = body,
format = options.format,
date = options.date,
}
c:setopt_ssl_verifypeer(0)
local t,h = {},{}
c:perform{
writefunction = function(s)
t[#t+1] = s
end,
headerfunction = function(s)
h[#h+1] = s
end,
}
c = nil
if args.keepraw then
args.keepraw:write(
"POST ",url,
"\r\n\r\n",
table.concat(h),
"\r\n\r\n",
table.concat(t))
end
local j = json.decode(table.concat(t))
return j
end
---
-- Make a new post from the body of a file, using the filename as
-- the title. The file is posted as-is, with no substitutions or
-- other changes.
local function postFile(filename)
local title = args.title or filename
local content = utils.readfile(filename, false)
if not content then return nil, "No such file" end
content = content .. '\n\r\n\r'
.. '*(Posted by wprest/wppost.)*\n\r'
local ok, err = wp_newPost(
title,
content,
args.category,
args.tags
)
return ok, err
end
---
-- Actual main body of the script. Read the command line for file name, user, and password.
-- Make the post as requested and show the result.
local ok, res = postFile(args.filename)
if ok then
if args.debug then
print(pretty.write(ok))
else
local ID = ok and ok.body and ok.body.ID or ok.ID
print("wppost success: New post ID=".. ID)
end
else
print("wppost failed:", res)
os.exit(1)
end
|