Skip to content

Instantly share code, notes, and snippets.

@cdent
Last active December 17, 2015 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdent/5608370 to your computer and use it in GitHub Desktop.
Save cdent/5608370 to your computer and use it in GitHub Desktop.
Two scripts to experiment with sorting revisions in a collection of tiddlers.
makeit.py just creates some bags, recipes and tiddlers to experiment with
each time it runs it will erase and recreate the store (if the text store
is being used)
listit.py gets all the tiddlers in a named recipe and then orders the
revisions within by modified time, irrespective of tiddler identity.
As written it processes a collection of tiddlers from a recipe but this
is not required: any sequence of tiddlers could be handled by the loop
that surrounds revision_tuples.
Is this fast? I don't (yet) know. It ought to be fairly memory efficient.
We throw away tiddler objects in favor of just keeping the necessary
data.
revision_tuples can limit the depth of revisions it will search. This
is probably useful in a situation where some tiddlers may be get a
lot of revisions. Not also the commented tiddler_to_old stuff.
It is unclear how it will perform for "all the tiddlers". That will largely
depend on how the current store is able to provide "all the tiddlers". On
something using the mysql store, you can get that pretty quickly with a
/search. It is likely that for other stores which don't provide that kind
of service energy is better spent on making that (small thing) effective
rather than creating an outside context problem with a different data
store for tracking changes.
Note that the version seen is better than the original versions that were
never posted. Those versions had two additional loops that proved unnecessary
when it became clear that just getting the right info into the revision_tuple
in the first place was the real crux of this biscuit.
"""
Make a revisions based recent changes of tiddlers
in some set of tiddlers.
For the moment "set of tiddlers" is not clearly
defined, we'll use a recipe but the algorithm out
to work for any sequence of tiddlers.
The (initial) desired outcome is a list of tiddler
revisions in descending order, irrespective of
tiddler identity.
The source data comes makeit.py. Those tiddlers
are guaranteed to have at least a few milliseconds
of difference between their mod times and are randomly
deposited in different bags to mess things up a bit.
"""
import sys
from tiddlywebplugins.utils import get_store
from tiddlyweb.config import config
from tiddlyweb.control import get_tiddlers_from_recipe
from tiddlyweb.model.recipe import Recipe
def revision_tuples(store, tiddler, revisions, modified_limit=None):
"""
Create a list of tuples of tiddler info for _this_
tiddler.
"""
data = []
for revision in revisions:
tiddler.revision = revision
tiddler = store.get(tiddler)
# untested, but we could choose to stop diving on tiddlers
# if a revision is too old
# if modified_limit and tiddler_too_old(tiddler, modified_limit)
# break
data.append((tiddler.title, tiddler.bag, tiddler.revision,
tiddler.modifier, tiddler.modified))
return data
def produce(recipe_name, max_depth=9999):
"""
max_depth limits how far back in revision history to go for
each tiddler.
Produce a list of tuples of tiddler data for future sortage.
"""
store = get_store(config)
recipe = store.get(Recipe(recipe_name))
tiddlers = get_tiddlers_from_recipe(recipe, {})
revision_data = []
for tiddler in tiddlers:
revision_data.extend(revision_tuples(store, tiddler,
store.list_tiddler_revisions(tiddler)[:max_depth]))
return revision_data
def sortdata(revision_data):
"""
Reorder on modified time of revision.
A more complex sort would be possible, for example to group
the same tiddler modified at the same time in its own lump.
The point is that once you have the data in a structured tuple,
the sort is "painless".
"""
print revision_data
return sorted(revision_data, key=lambda x: int(x[4]), reverse=True)
def present(data):
for tiddler in data:
title, bag, revision, modifier, modified = tiddler
print '%s in bag %s' % (title, bag)
print '\tmodified on %s by %s' % (modified, modifier)
print '\trevision %s link goes here' % revision
print
if __name__ == '__main__':
name = sys.argv[1] if len(sys.argv) >= 2 else 'houses'
revision_data = produce(name)
flattened_data = sortdata(revision_data)
present(flattened_data)
"""
Make a few recipes bags and tiddlers with revisions.
"""
import shutil
import random
import string
import time
from copy import copy
from tiddlywebplugins.utils import get_store
from tiddlyweb.model.bag import Bag
from tiddlyweb.model.tiddler import Tiddler
from tiddlyweb.model.recipe import Recipe
from tiddlyweb.config import config
NAMES = ['alpha', 'beta', 'gamma']
def reset():
try:
shutil.rmtree('store')
except:
pass
def random_recipe():
names = copy(NAMES)
random.shuffle(names)
print 'names', names
return [(name, '') for name in names]
def random_string(length):
return ''.join(random.choice(string.lowercase) for i in range(length))
def make():
store = get_store(config)
for name in NAMES:
bag = Bag(name)
store.put(bag)
for name in ['cars', 'houses']:
recipe = Recipe(name)
recipe_list = random_recipe()
print 'rl', recipe_list
recipe.set_recipe(recipe_list)
store.put(recipe)
for j in range(10):
for i in range(10):
tiddler = Tiddler('title%s' % random.randint(0, 20),
NAMES[random.randint(0, 2)])
print 'bag', tiddler.bag
tiddler.text = random_string(random.randint(10, 100))
tiddler.modifier = random_string(5)
store.put(tiddler)
time.sleep(.15)
if __name__ == '__main__':
reset()
make()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment