#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 GFORGX <gforgx@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of the nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
__version__ = '1.0'
__description__ = 'Package for easy notes management'
__author__ = "GFORGX (gforgx@gmail.com)"
__copyright__ = "Copyright 2008, GFORGX"
__license__ = "BSD (revised)"
import os
from string import strip
from shutil import copyfile
from urllib2 import urlopen
from time import localtime
today = str(localtime()[0]) + '-' + str(localtime()[1]) + '-' + str(localtime()[2])
class Storage(self):
def __init__(self):
path = os.path.expanduser('~/Notes/Date')
tagPath = os.path.expanduser('~/Notes/Tag')
def getDates(self):
''' Returns list of all dates '''
list = []
for date in os.listdir(self.path):
list.append(Date(date))
return list
def getDatesNumber(self):
''' Returns total dates number '''
return len(self.getDates())
def getTags(self):
''' Returns list of all tags '''
list = []
for tag in os.listdir(self.tagPath):
list.append(Tag(tag))
return list
def getTagsNumber(self):
''' Returns total tags number '''
return len(self.getTags())
class Note:
def __init__(self, name):
self.name = name
def exists(self):
''' Returns True if note exists and False if not'''
if self.getPath() == None:
return False
else:
return True
def getDate(self):
''' Returns creation date of selected note '''
for date in Storage.getDates():
if date.hasNote(self.name):
return date
def getPath(self):
''' Returns file path for selected note '''
return os.path.join(Storage.path, self.getDate().value, self.name)
def getText(self):
text = None
''' Returns full text for selected note '''
if self.exists():
file = open(self.getPath(), 'r')
text = ''.join(file.readlines())
return Text(text)
def getTags(self):
''' Returns tags applied to selected note '''
tags = []
if self.exists():
for tag in Storage.getTags():
if tag.hasNote(self.name):
tags.append(tag)
return tags
def getKeywords(self):
''' Returns list containing 5 most commonly used words in text '''
keywords = []
if self.exists():
words = {}
for line in open(self.getPath(), 'r'):
line = strip(line, " \n")
for word in line.split(" "):
try:
words[word] += 1
except KeyError:
words[word] = 1
pairs = words.items()
pairs.sort(lambda a, b: b[1]-a[1])
for p in pairs[:5]:
keywords.append(p[0])
return keywords
def remove(self):
''' Removes note and date/tag dirs if empty '''
if self.exists():
os.remove(self.getPath())
self.getDate().remove()
for tag in self.getTags():
os.unlink(os.path.join(tag_path, tag.value, self.name))
tag.remove()
def write(self, text):
''' Writes some text to note '''
if not self.exists():
Date(today).create()
file = open(os.path.join(path, today, self.name), 'w')
file.write(text)
file.close()
else:
file = open(self.getPath(), 'w')
file.write(text)
file.close()
def tag(self, tags):
''' Applies user given tags to note '''
if self.exists():
src = self.getTags()
for tag in tags:
Tag(tag).create()
if self not in Tag(tag).getNotes():
os.symlink(self.getPath(), os.path.join(tag_path, tag, self.name))
for tag in src:
if tag.value not in tags:
os.unlink(os.path.join(tag_path, tag.value, self.name))
tag.remove()
def importFile(self, filePath):
''' Imports specified local file as a new note '''
if not self.exists():
if os.path.exists(filePath) and os.path.isfile(filePath):
Date(today).create()
copyfile(filePath, os.path.join(path, today, self.name))
def importUrl(self, url):
''' Saves text from specified web page as new note '''
if not self.exists():
try:
page = urlopen(url)
text = ''.join(page.readlines())
self.write(text)
except:
pass
class Date:
def __init__(self, date):
self.value = date
def exists(self):
''' Returns True if date exists and False if not '''
if self in Storage.getDates():
return True
else:
return False
def getPath(self):
''' Returns path for selected date '''
if self.exists():
return os.path.join(Storage.path, self.value)
def getNotes(self):
''' Returns list that contains notes created at selected date '''
notes = []
if self.exists():
for note in os.listdir(self.getPath()):
notes.append(Note(note))
return notes
def getNumber(self):
''' Returns number of notes created at selected date '''
return len(self.getNotes())
def remove(self):
''' Removes selected date if there are no notes created at it '''
if self.exists() and self.getNumber() == 0:
os.rmdir(self.getPath())
def create(self):
''' Creates specified date '''
dir = os.path.join(Storage.path, self.value)
if not self.exists():
os.mkdir(dir)
def hasNote(self, name):
if name in self.getNotes():
return True
else:
return False
class Tag:
def __init__(self, tag):
self.value = tag
def exists(self):
''' Returns True if tag exists and False if not '''
if self in Storage.getTags():
return True
else:
return False
def getPath():
''' Returns path for selected tag '''
if self.exists():
return os.path.join(Storage.tag_path, self.value)
def getNotes(self):
''' Returns list that contains notes tagged with selected tag '''
notes = []
if self.exists():
if os.path.exists(self.getPath()):
for note in os.listdir(self.getPath()):
notes.append(Note(note))
return notes
def getNumber(self):
''' Returns number of notes tagged with selected tag '''
return len(self.getNotes())
def remove(self):
''' Removes selected tag if there are now notes tagged with it '''
if self.exists() and self.getNumber() == 0:
os.rmdir(self.getPath())
def create(self):
''' Creates specified tag '''
dir = os.path.join(Storage.tagPath, self.value)
if not os.path.exists(tag_dir):
os.mkdir(tag_dir)
def hasNote(self, name):
if name in self.getNotes():
return True
else:
return False
class Text:
def __init__(self, text):
self.value = text
def getNotes(self):
''' Returns notes that contains specified text fragment '''
notes = []
if self.value != None:
for dir in os.listdir(path):
for note in os.listdir(os.path.join(path, dir)):
if self.value in ''.join(open(os.path.join(path, dir, note)).readlines()):
notes.append(Note(note))
return notes
def getNumber(self):
''' Returns number of notes that contain specified text fragment '''
return len(self.getNotes())
class Search:
def __init__(self, items):
self.items = items
def getNotes(self):
''' Returns list that contains notes matching all search items '''
full_list = []
for item in self.items:
notes = []
for note in Date(item).getNotes():
if note not in notes:
notes.append(note.name)
for note in Tag(item).getNotes():
if note not in notes:
notes.append(note.name)
for note in Text(item).getNotes():
if note not in notes:
notes.append(note.name)
if Note(item).getPath() != None:
if item not in notes:
notes.append(Note(item).name)
full_list.append(notes)
list_intersection = lambda list: set(list[0]) if len(list) == 1 else set(list[0]).intersection(list_intersection(list[1::]))
names = list(list_intersection(full_list))
results = []
for name in names:
results.append(Note(name))
return results
def getNumber(self):
''' Returns number of notes matching all search items '''
return len(self.getNotes())