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 |
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 |