Hey All,
Still new to authoring in Confluence... The main reason we went to Confluence is because our engineers had a major pain point in providing review comments using Adobe Acrobat Review Server. Their hope is that they can modify small details directly in the source, AND provide comments on pages. (Don't tell me it's a terrible idea, because I lost that battle.)
So, now each page in a doc has a growing list of comments. Tracking this activity, even on a small document, is so flawed! I have no way of marking a comment done, filtering only unresolved comments, seeing a history of added and deleted comments, etc. So, what is already happening is that I'm missing newly added comments/replies to threads. So, I started deleting comments once I incorporated them until I needed to go back and see the comment again and had no way to restore it.
I'm so frustrated. There is no way this is going to work on bigger docs. WAY too error prone...
Does anyone know if there's an add-on? Or a different way to get/track feedback on the actual Confluence page (not a PDF output, since they don't want to review that way). HELP???
TIA!
Firstly it is a brilliant idea!! (sorry you lost the battle again )
Our industry association Working Groups uses Confluence for drafting reference documents for ultimately publishing to the industry.
Each Chapter of the document is drafted directly on screen.
There are two commenting methods now (depending on your version - we have v5.8.16)
Page Comments are added at the bottom of the page in "threads", but as you have noticed there is no way to mark them as "resolved"
But the new "In-line Comment" facility allows you to highlight some text in normal View mode and a pop up box appears e.g.
image2017-2-4 9:48:57.png
That then gives a comment box that also has an option to mark it as Resolved
image2017-2-4 9:50:3.png
Just for information. There is the add-on called Talk. It has many features and in some cases can be even better than Confluence inline comments (it allows you to insert inline comments too). You can also try it without installing to your instance, the team created a demo server for this purpose.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
This is a good approach. But sometimes authors use a different tool to author content.
Can we have a plugin from the authoring tool to launch confluence.
Thanks,
Nuz
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
We use Confluence for collaborative review comments between ourselves and the customer. Inline comments work well, with footer comments being used for things like saying "I've reviewed this page, back to you for updates". One thing that was difficult is tracking all the comments collectively, so we wrote a PHP macro that walks the pages below a starting page, fetches all the comments, and then builds a single review comments page below the same parent with all the comments from all child pages on it. That helps because you can't see the actual comment when you go to edit the page to resolve it (a major flaw IMHO).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Adrian,
we are looking for a similar comments tracking solution. Would you be able to share/sell such script? Does it also work for comments under the page?
Thanks for letting me know.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here's the Python code (we upgraded from PHP) that produces the table above. Apologies for not replying sooner hieroglyf - I've only just seen this !
It's crude code without much error checking (don't judge!) but does the job. It should be obvious to a decent coder what needs to change to work on your instance (be it Cloud or Hosted). Feedback welcome.
Usual disclaimer, you are free to use this code, but please attribute the author. No liability will be accepted for your use of this software (it does write new pages to your instance via the brilliant API services - thanks Atlassian).
--
import requests
import json
from requests.auth import HTTPBasicAuth
from pprint import pprint
import csv, re, datetime
import urllib.parse
import html
from datetime import datetime
from html.parser import HTMLParser
# Author: Adrian Hepworth / Worldline
# Licensed under Creative Commons - CC BY-SA 4.0
# The base content API - change to point at your instance
contenturl = 'https://organisation.atlassian.net/wiki/rest/api/content'
# The space ID in which the parent page resides
space = "SPACE"
# The Parent Page
source = "My Page"
# Get the username and password from a local CSV file called 'atlassian-login.txt'
with open('atlassian-login.txt', newline='') as csvfile:
cred_reader = csv.reader(csvfile, delimiter=',', quotechar='"')
for item in cred_reader:
username=item[0]
token=item[1]
auth = HTTPBasicAuth(username,token)
comment_list = []
def escape(s):
# this has to be first:
s = s.replace("&", "&")
s = s.replace("<", "<")
s = s.replace(">", ">")
s = s.replace('\\n', "<br />")
s = s.replace('\n', "<br />")
return s
class MLStripper(HTMLParser):
def __init__(self):
super().__init__()
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def get_data(self):
return ''.join(self.fed)
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
def find_page(space,title):
global contenturl
params = {'spaceKey':space,
'title':title}
resp = requests.get(contenturl,params=params,auth=auth)
if resp.status_code != 200:
return None
results = json.loads(resp.text)
if results['size'] == 0:
return None
page=results['results'][0]
return page
def get_url(url,params):
#print("Get URL for %s with %s params" % (url,params))
global auth
resp = requests.get(url,params=params,auth=auth)
if resp.status_code != 200:
return None
results = json.loads(resp.text)
if results['size'] == 0:
return None
return results
def get_comment_list(id,url):
global comment_list
print("Going for %s,%s,%s with %d comments so far" % (space,id,url,len(comment_list)))
params = {'expand':'extensions.inlineProperties,extensions.resolution,history,body.view'
,'limit':'125'
,'depth':'all'}
comments = get_url(url+'/child/comment',params=params)
# print("There are %d comments\nComments: %s" % (len(comments),comments)); exit()
if comments:
for comment in comments['results']:
# print('\nComment: %s' % comment)
if comment['extensions']['location']=='inline':
comment_list.append({'page' : comment['title'],
'pageURL' : comment['_links']['self'],
'pageUI' : comments['_links']['base']+comment['_links']['webui'],
'location' : comment['extensions']['location'],
'status' : comment['extensions']['resolution']['status'],
'selection' : comment['extensions']['inlineProperties']['originalSelection'],
'title' : comment['title'],
'who' : comment['history']['createdBy']['publicName'],
'when' : comment['history']['createdDate'],
'link' : comment['_links']['self'],
'web' : comments['_links']['base']+comment['_links']['webui'],
'comment' : strip_tags(html.unescape(comment['body']['view']['value']))}
)
#print (comment_list)
# Recurse to call itself to walk the tree
content = get_url(url+'/child/page',{'limit':150});
if content:
for childPage in content['results']:
# Append the comments on each page
print('Found child page: %s' % childPage['id'])
get_comment_list(childPage['id'],childPage['_links']['self'])
# Find the parent page
start_page = find_page(space,source)
get_comment_list(start_page['id'],start_page['_links']['self'])
body = "<h1>Comment Extract</h1>"
body += '<table class=\"wrapped fixed-table\"><colgroup><col style=\"width: 150px;\" /> <col style=\"width: 100px;\" /> <col style=\"width: 100px;\" /> <col style=\"width: 600px;\" /> </colgroup><tbody><tr><th>Page</th><th>Location</th><th>Status</th><th>Comments</th></tr>';
for ix,comment in enumerate(comment_list):
# print(comment)
# output the comment
if comment['location'] != "inline":
# Complete new line
if ix>0:
body += "</td></tr>"
body += '<tr><td><a href=\"'+escape(comment['pageUI'])+'\">'+escape(comment['page'])+'</a></td>'
body +='<td class=\"highlight-blue\" data-highlight-colour=\"blue\">'+comment['location']+'</td>'
body += '<td>'+comment['status']+'</td>'
body += '<td><a href=\"'+escape(comment['web'])+'\">'+comment['who']+'</a> - '+comment['when']
body += '<br />'+escape(comment['comment'])
else:
if comment['selection'] == "":
# This is a reply to a comment
body += '<br /><a href=\"'+escape(comment['web'])+'\">'+comment['who']+'</a> - '+comment['when']
body += '<br />'+escape(comment['comment'])
else:
if ix>0:
body += "</td></tr>"
body += '<tr><td><a href=\"'+escape(comment['pageUI'])+'\">'+escape(comment['page'])+'</a></td>'
body += '<td>'+comment['location']+'</td>'
if comment['status'] == "resolved" or comment['status'] == "dangling":
body += '<td class=\"highlight-green\" data-highlight-colour=\"green\">'+comment['status']+'</td>'
else:
body += '<td>'+comment['status']+'</td>'
body += '<td><span style=\"color: blue;\"><em>'+escape(comment['selection'])+'</em></span>'
body += '<br /><a href=\"'+escape(comment['web'])+'\">'+comment['who']+'</a> - '+comment['when']
body += '<br />'+escape(comment['comment'])
body += '</td></tr></tbody></table>'
title = "Comments extracted on %s" % datetime.today().strftime('%Y-%m-%d %H:%M:%S')
header = {'Content-Type': 'application/json'}
reqbody = {"type":"page",
"title":title,
"space":{"key":space},
"ancestors":[{"id":start_page['id']}],
"metadata":{"labels":[{"name":"no-print"}]},
"body":{"storage":{"value":body,
"representation":"storage"}}}
resp = requests.post(contenturl,headers=header,json=reqbody,auth=auth)
if resp.status_code != 200:
print('Unable to process creation - response %s' % resp.status_code)
print('Response: %s' % resp.text)
exit()
page = resp.json()
print('Successfully created page id (%s)\n' % page['id'])
exit()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You'll need to re-tab the code as it's pasted without correct Python tabs.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.