def _complete_original_tasks(self, setName): """*mark original tasks as completed if they are marked as complete in the index taskpaper document* **Key Arguments:** - ``setName`` -- the name of the sync tag set """ self.log.info('starting the ``_complete_original_tasks`` method') if self.editorialRootPath: taskpaperDocPath = self.syncFolder + "/e-" + \ self.workspaceName + "-" + setName + "-tasks.taskpaper" else: taskpaperDocPath = self.syncFolder + "/" + \ self.workspaceName + "-" + setName + "-tasks.taskpaper" exists = os.path.exists(taskpaperDocPath) if not exists: return # OPEN TASKPAPER INDEX FILE doc = document(taskpaperDocPath) doneTasks = doc.tagged_tasks("@done") for t in doneTasks: theseNotes = t.notes parent = t.parent while not len(theseNotes) and parent and parent.parent: theseNotes = parent.notes parent = parent.parent if self.editorialRootPath: theseNotes[0].title = theseNotes[0].title.replace( "editorial://open", self.editorialRootPath).replace("?root=dropbox", "") theseNotes[0].title = urllib.unquote( theseNotes[0].title).replace("%40", "@") originalFile = theseNotes[0].title.split(" > ")[0].strip() if len(theseNotes[0].title.split(" > ")) > 1: projectName = theseNotes[0].title.split(" > ")[1].strip() else: projectName = False odoc = document(originalFile) odoc.tidy() odoc.save() odoc = document(originalFile) if projectName: thisObject = odoc.get_project(projectName) else: thisObject = odoc oTask = thisObject.get_task(t.title) if oTask: oTask.done("all") odoc.save() self.log.info('completed the ``_complete_original_tasks`` method') return None
def _create_single_taskpaper_task_list(self, content, setName): """*create single, sorted taskpaper task list from content pulled in from all of the workspace taskpaper docs* **Key Arguments:** - ``content`` -- the content to add to the taskpaper task index - ``setName`` -- the name of the sync tag set **Return:** - ``taskpaperDocPath`` -- path to the task index taskpaper doc """ self.log.info( 'starting the ``_create_single_taskpaper_task_list`` method') taskpaperDocPath = None if len(content): # content = content.decode("utf-8") if self.editorialRootPath: taskpaperDocPath = self.syncFolder + "/e-" + \ self.workspaceName + "-" + setName + "-tasks.taskpaper" else: taskpaperDocPath = self.syncFolder + "/" + \ self.workspaceName + "-" + setName + "-tasks.taskpaper" try: self.log.debug("attempting to open the file %s" % (taskpaperDocPath, )) writeFile = codecs.open(taskpaperDocPath, encoding='utf-8', mode='w') except IOError, e: message = 'could not open the file %s' % (taskpaperDocPath, ) self.log.critical(message) raise IOError(message) writeFile.write(content) writeFile.close() # OPEN TASKPAPER FILE if self.editorialRootPath: doc = document(self.syncFolder + "/e-" + self.workspaceName + "-" + setName + "-tasks.taskpaper") else: doc = document(self.syncFolder + "/" + self.workspaceName + "-" + setName + "-tasks.taskpaper") doc.sort_projects(workflowTags=self.workflowTags) doc.sort_tasks(workflowTags=self.workflowTags) doc.save()
def _sort_tp_file(self, taskpaperPath): """*sort individual taskpaper documents* **Key Arguments:** - ``taskpaperPath`` -- path to a taskpaper file **Return:** - None """ self.log.info('starting the ``_sort_tp_file`` method') # OPEN TASKPAPER FILE self.log.info("sorting taskpaper file %(taskpaperPath)s" % locals()) doc = document(taskpaperPath) doc.tidy() doc.sort_tasks(self.settings["workflowTags"]) doc.sort_projects(self.settings["workflowTags"]) doc.save() self.log.info('completed the ``_sort_tp_file`` method') return None
def test_doc2_function(self): # READ IN A TASKPAPER FILE from tastic.tastic import document taskpaperFile = pathToOutputDir + "/ssdr3.taskpaper" doc = document(taskpaperFile) # DISPLAY THE RAW CONTENT OF THE DOCUMENT # print doc.raw_content # DOCUMENT PROJECTS docProjects = doc.projects firstProject = docProjects[0] # TASK PAPER PROJECT ATTRIBUTES # print firstProject.raw_content # print firstProject.content # print firstProject.title # print firstProject.parent # print "\n\n" # DOCUMENT NOTES # print "NOTES:" docNotes = doc.notes # for n in docNotes: # print n.title # print "\n\n" # GET A PROJECT archiveProject = doc.get_project("Archive") # print archiveProject.title # print archiveProject.to_string() # print "\n\n" # print "FILTER PROJECTS BY TAG" filteredProjects = doc.tagged_projects("flag") # for p in filteredProjects: # print p.title # print "FILTER TASK BY TAG" filteredTasks = doc.tagged_tasks("@flag") # for t in filteredTasks: # print t.title print "TIDY DOCUMENT" # doc.tidy() # print "SORT PROJECTS" doc.sort_projects("@due, @flag, @hold, @next, @someday, @wait") # print "SORT TASKS" doc.sort_tasks("@due, @flag, @hold, @next, @someday, @wait") # print "ADD PROJECT" # doc.add_project("this is a project I added", "@with @tags") # doc.add_project("this is a second project I added", "@with @tags") # for p in docProjects: # p.add_project( # ">>>>>>>>>>>>>>>> this is a subproject I added", "@with @tags") # p.add_project(">>>>>>>>>>>>>>>> and another added subproject:", # ['@with', '@tags(data)']) # print "ADD TASKS" # doc.add_task("this is a task I added", "@with @tags") # doc.add_task("and another added task", # ['@with', '@tags(data)']) # print "ADD NOTE" # doc.add_note("""Nullam dignissim vulputate nulla vel fermentum. Praesent in nibh efficitur, accumsan tellus at, tincidunt quam. Curabitur enim leo, condimentum eget bibendum ac, suscipit id tortor. Proin sed placerat mauris. Pellentesque in eleifend massa. Fusce tincidunt eget risus at scelerisque. Mauris vel rutrum arcu, sit amet tempus nibh. Praesent volutpat elit sed felis luctus, a accumsan nisl convallis. Nullam eros ex, malesuada eget turpis sodales, sollicitudin tempus est. Vivamus odio augue, ornare non imperdiet eleifend, gravida id velit. Phasellus a congue felis. Morbi pharetra sit amet nulla id mattis. Sed sagittis, ex maximus pellentesque suscipit, mi diam fringilla tortor, eu faucibus lorem lorem et odio. Donec blandit nec quam sit amet facilisis. Sed nec sodales nulla, in pretium libero. Fusce tempus lorem vel ligula euismod tincidunt.""") # doc.add_note( # """And another note with a link http://www.thespacedoctor.co.uk""") # # # DOCUMENT SEARCHES # docSearches = doc.searches # print docSearches # # DOCUMENT TASKS # print "TASKS:" # docTasks = doc.tasks # print docTasks # print "\n\n" # print "\n\n" # print "GET PROJECT" # archiveProject = doc.get_project("Archive") # if archiveProject: # print archiveProject.to_string() # print "\n\n" doc.save() print doc.to_string() return
def _create_html_tasklist(self, taskpaperDocPath): """*create an html version of the single taskpaper index task list* **Key Arguments:** - ``taskpaperDocPath`` -- path to the task index taskpaper doc **Return:** - ``htmlFilePath`` -- the path to the output HTML file """ self.log.info('starting the ``_create_html_tasklist`` method') if self.editorialRootPath: return title = self.workspaceName content = "<h1>%(title)s tasks</h1><ul>\n" % locals() # OPEN TASKPAPER FILE doc = document(taskpaperDocPath) docTasks = doc.tasks for task in docTasks: tagString = " ".join(task.tags) tagString2 = "" for t in task.tags: t1 = t.split("(")[0] tagString2 += """ <span class="%(t1)s tag">@%(t)s</span>""" % locals( ) notes = task.notes filepath = notes[0].title.split(" > ")[0] basename = os.path.basename(filepath).replace(".taskpaper", "").replace( "-", " ") filepath = "dryx-open://" + filepath taskTitle = u"""<a href="%(filepath)s"><span class="bullet %(tagString)s">◉</span> </a>""" % locals() + \ task.title[2:] + tagString2 if len(notes[0].title.split(" > ")) > 1: parent = notes[0].title.split(" > ")[1] parent = """<span class="parent">%(basename)s > %(parent)s</span></br>\n""" % locals( ) else: parent = """<span class="parent">%(basename)s</span></br>\n""" % locals( ) taskContent = """</span>\n\t\t</br><span class="notes">""".join( task.to_string(title=False, indentLevel=0).split("\n")[1:]) if len(taskContent): taskContent = """\n\t<br><span class="notes">""" + \ taskContent + """\n\t</span>""" else: taskContent = "" htmlTask = """<li class="XXX">%(parent)s%(taskTitle)s%(taskContent)s</li>\n""" % locals( ) content += htmlTask content += "</ul>" htmlFilePath = taskpaperDocPath.replace(".taskpaper", ".html") try: self.log.debug("attempting to open the file %s" % (htmlFilePath, )) writeFile = codecs.open(htmlFilePath, encoding='utf-8', mode='w') except IOError, e: message = 'could not open the file %s' % (htmlFilePath, ) self.log.critical(message) raise IOError(message)
def _get_tagged_content_from_taskpaper_files(self, taskpaperFiles, tagSet, editorial=False, workflowTagSet=False, includeFileTags=True): """*get all tasks tagged with a sync-tag from taskpaper files* **Key Arguments:** - ``taskpaperFiles`` -- paths to all taskpaper files in workspace - ``tagSet`` -- the tagset to extract from the taskpaper files. - ``editorial`` -- format links for editorial ios apps - ``workflowTagSet`` -- does the tag set contain workflow tags (if not skip the non-live project lists) - ``includeFileTags`` -- if the tag is in the filepath (e.g. /@due/mytasks.taskpaper) include all items the file in that tag set **Return:** - ``content`` -- the given tagged content of all taskpaper files in a workspace (string) """ self.log.info( 'starting the ``_get_tagged_content_from_taskpaper_files`` method') content = "" for tp in taskpaperFiles: done = False if not workflowTagSet: for tag in ["@next", "@hold", "@done", "@someday"]: if "/" + tag + "/" in tp: done = True if done: continue # OPEN TASKPAPER FILE doc = document(tp) basename = os.path.basename(tp).replace("-", " ").upper() archive = doc.get_project("Archive") if archive: archive.delete() fileTagged = False done = False for tag in tagSet: if includeFileTags == True: tag = "@" + tag.replace("@", "") if "/%(tag)s/" % locals() in tp: fileTagged = True if "/@done/" in tp: done = True if done: continue # GENERATE THE EDITORIAL FILE LINK if self.editorialRootPath: tp = urllib.quote(tp) tp = tp.replace(self.editorialRootPath, "editorial://open") + "?root=dropbox" for tag in tagSet: tag = "@" + tag.replace("@", "") etag = "%40" + tag.replace("@", "") # DETERMINE THE SUBORDINATE/HIGH LEVEL TAGS lesserTags = [] greaterTags = [] if workflowTagSet: trumped = False else: trumped = True for t in self.workflowTags: if t == tag: trumped = True if t != tag: if trumped: lesserTags.append(t) else: greaterTags.append(t) # FOR DOCUMENT WITH THIS SYNC TAG filteredTasks = [] if ("/%(tag)s/" % locals() in tp or "/%(etag)s/" % locals() in tp) and includeFileTags == True: filteredTasks = doc.all_tasks() for ft in filteredTasks: trumped = False for t in ft.tags: if t in " ".join(greaterTags): trumped = True if not trumped: for t in lesserTags: ft.del_tag(t) ft.add_tag(tag) elif not fileTagged: filteredProjects = doc.tagged_projects(tag) for p in filteredProjects: allTasks = p.all_tasks() for ft in filteredTasks: trumped = False for t in ft.tags: if t in " ".join(greaterTags): trumped = True if not trumped: for t in lesserTags: ft.del_tag(t) ft.add_tag(tag) filteredTasks = doc.tagged_tasks(tag) for ft in filteredTasks: if "done" not in "".join(ft.tags): if "Project" in ft.parent.__repr__(): thisNote = tp + " > " + ft.parent.title[:-1] else: thisNote = tp ft.add_note(thisNote) content += ft.to_string() + "\n" self.log.info( 'completed the ``_get_tagged_content_from_taskpaper_files`` method' ) return content
def test_doc_function(self): # READ IN A TASKPAPER FILE from tastic.tastic import document taskpaperFile = pathToOutputDir + "/saturday-tasks.taskpaper" doc = document(taskpaperFile) # TIDY THE DOCUMENT doc.tidy() # SAVE A DUPLICATE OF THE DOC doc.save(pathToOutputDir + "/saturday-tasks-copy.taskpaper") # ADD SAVE THE ORIGINAL doc.save(pathToOutputDir + "/saturday-tasks.taskpaper") # LIST THE PROJECT IN THE DOC docProjects = doc.projects for p in docProjects: continue print p.title # FILTER PROJECTS dueProjects = doc.tagged_projects("@due") for p in dueProjects: continue print p.title # GET A PROJECT BY NAME gardenProject = doc.get_project("tidy the garden") # SORT PROJECTS doc.sort_projects("@due, @flag, @hold, @next, @someday, @wait") doc.save() # gardenProject.refresh # ADD A NEW PROJECT shedProject = gardenProject.add_project( title="build a shed", tags="@someday @garden" ) gardenProject.refresh researchShedProject = shedProject.add_project( title="research shed designs", tags="@research" ) coffee = doc.get_project("make coffee").done() doc.get_project("replace hedge with fence").delete() docTasks = doc.tasks for t in docTasks: continue print t.title hotTasks = doc.tagged_tasks("@hot") for t in hotTasks: continue print t.title doc.sort_tasks("@due, @flag, @hold, @next, @someday, @wait") doc.save() coffee.refresh for t in coffee.tasks: t.done("all") print "" aTask = researchShedProject.add_task( "look for 5 videos on youtube", "@online") bTask = aTask.add_task("note the urls of the most useful videos") # NOTES doc.get_project("grocery shop").notestr() newNote = doc.add_note( "make sure to make time to do nothing") # print aTask.tasks newNote = aTask.add_note( "good video: https://www.youtube.com/watch?v=nMaGTP82DtI") aTask.add_tag("@due") # print aTask.to_string() researchShedProject.add_tag("@hold") # print researchShedProject.to_string() aTask.set_tags("@someday") # print aTask.to_string() researchShedProject.set_tags("@someday") # print researchShedProject.to_string() aTask.set_tags() # print aTask.to_string() doc.save()
class workspace(): """ *tools for sorting, archiving and indexing tasks and maintaining the contents of all taskpaper files within a given workspace* **Key Arguments:** - ``log`` -- logger - ``fileOrWorkspacePath`` -- the root path of the workspace you wish to sort the taskpaper docs within, or the path to a single taskpaper file - ``settings`` -- the settings dictionary **Usage:** To setup your logger, settings and database connections, please use the ``fundamentals`` package (`see tutorial here <http://fundamentals.readthedocs.io/en/latest/#tutorial>`_). To initiate a taskpaper workspace object, use the following: .. code-block:: python from tastic.workspace import workspace ws = workspace( log=log, settings=settings, fileOrWorkspacePath="/path/to/root/of/workspace" ) or to target a single taskpaper document use instead the path to the file: .. code-block:: python from tastic.workspace import workspace ws = workspace( log=log, settings=settings, fileOrWorkspacePath="/path/to/doc.taskpaper" ) """ # Initialisation def __init__(self, log, fileOrWorkspacePath, settings=False): self.log = log log.debug("instansiating a new 'sort' object") self.settings = settings self.taskpaperPath = False self.workspaceRoot = False # xt-self-arg-tmpx # INITIAL ACTIONS # ARE WE DEALING WITH A WORKSPACE DIRECTORY OR SINGLE FILE if os.path.isfile(fileOrWorkspacePath): self.taskpaperPath = fileOrWorkspacePath else: self.workspaceRoot = fileOrWorkspacePath self.taskpaperFiles = self._get_all_taskpaper_files() return None def sort(self): """ *sort the workspace or individual taskpaper document via the workflow tags found in the settings file* **Usage:** To sort all of the taskpaper documents in the workspace via the workflow tag set with the settings file, for example: .. code-block:: yaml workflowTags: "@due, @flag, @hold, @next, @someday, @wait" use the ``sort()`` method: .. code-block:: python ws.sort() """ self.log.info('starting the ``sort`` method') for f in self.taskpaperFiles: self._sort_tp_file(f) self.log.info('completed the ``sort`` method') return None def archive_done(self): """*move done tasks from the document's 'Archive' project into an adjacent markdown tasklog file* **Usage:** To move the archived tasks within a workspace's taskpaper docs into ``-tasklog.md`` files use the ``archive_done()`` method: .. code-block:: python ws.archive_done() """ self.log.info('starting the ``archive_done`` method') for f in self.taskpaperFiles: self._archive_tp_file_done_tasks(f) self.log.info('completed the ``archive_done`` method') return None def _get_all_taskpaper_files(self): """*get a list of all the taskpaper filepaths in the workspace* **Return:** - ``taskpaperFiles`` -- a list of paths to all the taskpaper files within the workspace """ self.log.info('starting the ``_get_all_taskpaper_files`` method') if self.workspaceRoot: from fundamentals.files import recursive_directory_listing theseFiles = recursive_directory_listing( log=self.log, baseFolderPath=self.workspaceRoot, whatToList="files" # all | files | dirs ) taskpaperFiles = [] taskpaperFiles[:] = [ f for f in theseFiles if os.path.splitext(f)[1] == ".taskpaper" ] else: taskpaperFiles = [self.taskpaperPath] self.log.info('completed the ``_get_all_taskpaper_files`` method') return taskpaperFiles def _sort_tp_file(self, taskpaperPath): """*sort individual taskpaper documents* **Key Arguments:** - ``taskpaperPath`` -- path to a taskpaper file **Return:** - None """ self.log.info('starting the ``_sort_tp_file`` method') # OPEN TASKPAPER FILE self.log.info("sorting taskpaper file %(taskpaperPath)s" % locals()) doc = document(taskpaperPath) doc.tidy() doc.sort_tasks(self.settings["workflowTags"]) doc.sort_projects(self.settings["workflowTags"]) doc.save() self.log.info('completed the ``_sort_tp_file`` method') return None def _archive_tp_file_done_tasks(self, taskpaperPath): """* archive tp file done tasks* **Key Arguments:** - ``taskpaperPath`` -- path to a taskpaper file **Return:** - None """ self.log.info('starting the ``_archive_tp_file_done_tasks`` method') self.log.info("archiving taskpaper file %(taskpaperPath)s" % locals()) taskLog = {} mdArchiveFile = taskpaperPath.replace(".taskpaper", "-tasklog.md") exists = os.path.exists(mdArchiveFile) if exists: pathToReadFile = mdArchiveFile try: self.log.debug("attempting to open the file %s" % (pathToReadFile, )) readFile = codecs.open(pathToReadFile, encoding='utf-8', mode='r') thisData = readFile.read() readFile.close() except IOError, e: message = 'could not open the file %s' % (pathToReadFile, ) self.log.critical(message) raise IOError(message) readFile.close() table = False for l in thisData.split("\n"): l = l.encode("utf-8") if ":---" in l: table = True continue if table == True and len(l) and l[0] == "|": dictt = collections.OrderedDict(sorted({}.items())) columns = l.split("|") dictt["task"] = columns[1].strip().decode("utf-8") dictt["completed"] = columns[2].strip().decode("utf-8") dictt["project"] = columns[3].strip().decode("utf-8") taskLog[dictt["task"] + dictt["completed"] + dictt["project"]] = dictt doc = document(taskpaperPath) aProject = doc.get_project("Archive") if not aProject: return doneTasks = aProject.tagged_tasks("@done") for task in doneTasks: dateCompleted = "" project = "" for t in task.tags: if "done" in t: dateCompleted = t.replace("done", "").replace("(", "").replace(")", "") if "project(" in t: project = t.replace("project", "").replace("(", "").replace(")", "") dictt = collections.OrderedDict(sorted({}.items())) notes = "" if task.notes: for n in task.notes: if len(notes) and notes[-2:] != ". ": if notes[-1] == ".": notes += " " else: notes += ". " notes += n.title if len(notes): notes = "<br><br>**NOTES:**<br>" + \ "<br>".join(textwrap.wrap( notes, 120, break_long_words=True)) dictt["task"] = "<br>".join( textwrap.wrap(task.title[2:], 120, break_long_words=True)) + notes dictt["task"] = dictt["task"].encode("utf-8") dictt["completed"] = dateCompleted dictt["project"] = project # SET ENCODE ERROR RETURN VALUE # RECODE INTO ASCII dictt["task"] = dictt["task"].decode("utf-8") dictt["completed"] = dictt["completed"].decode("utf-8") dictt["project"] = dictt["project"].decode("utf-8") taskLog[dictt["task"] + dictt["completed"] + dictt["project"]] = dictt taskLog = taskLog.values() taskLog = sorted(taskLog, key=itemgetter('task'), reverse=True) taskLog = sorted(taskLog, key=itemgetter('project'), reverse=True) taskLog = sorted(taskLog, key=itemgetter('completed'), reverse=True) dataSet = list_of_dictionaries(log=self.log, listOfDictionaries=taskLog) markdownData = dataSet.markdown(filepath=None) try: self.log.debug("attempting to open the file %s" % (mdArchiveFile, )) writeFile = codecs.open(mdArchiveFile, encoding='utf-8', mode='w') except IOError, e: message = 'could not open the file %s' % (mdArchiveFile, ) self.log.critical(message) raise IOError(message)