def create_rev_entry(rev_path, session, rev=None, recurse=False): """(string, Session, Revision)-> none Create a database entry for a given (or the current) revision """ if rev_path == u'': rev_path = u'.' if rev is None: pyrev = pysvn.Revision(pysvn.opt_revision_kind.head) else: pyrev = pysvn.Revision(pysvn.opt_revision_kind.number, rev.id) client = get_client() info_list = client.info2(rev_path, revision=pyrev, recurse=recurse) for path, info in info_list: if recurse: # For some reason, the top level dir is called trunk in the # recursive info, but paths under the top level dir don't contain # that part. if path != "trunk": path = unicode(path) else: path = u"." else: # restore the old path, client.info2 only has the top level name path = unicode(rev_path) if rev is None: revision = get_create_revision(path, session, info.last_changed_rev.number) else: revision = rev if revision is None: print "failed to find revision" continue if info.kind == pysvn.node_kind.dir: old_dir = session.query(Dir).get(path) if old_dir is not None: old_dir.revision = revision session.add(revision) continue # '.' does not look nice for the breadcrumb path if path == u".": dir_name = u"/" else: dir_name = unicode(os.path.basename(path)) new_dir = Dir(path, dir_name, unicode(info.repos_root_URL)) new_dir.revision = revision parent_path = unicode(os.path.dirname(path)) # top level dirs have an empty parent, not "trunk", just to make # parsing more fun if parent_path == u"": parent_path = u"." parent_dir = session.query(Dir).get(parent_path) if parent_dir is not None and path != u".": new_dir.parent = parent_dir session.add(new_dir) elif info.kind == pysvn.node_kind.file: if not os.path.exists(path): continue old_file = session.query(File).get(unicode(path)) if old_file is not None: old_file.size = os.path.getsize(path) old_file.revision = revision parent = old_file.directory while parent is not None: parent.revision = revision session.add(parent) parent = parent.parent session.add(old_file) continue new_file = File(path, os.path.basename(path), os.path.getsize(path), info.repos_root_URL) new_file.revision = revision parent_path = unicode(os.path.dirname(path)) if parent_path == u'': parent_path = u'.' parent_dir = session.query(Dir).get(parent_path) if parent_dir is None: raise Exception("Rats, pysvn has the same problem with missing parent dirs") new_file.directory = parent_dir session.add(new_file) tags = [] tags.append(get_tag_from_path(session, new_file.path)) tags.append(get_tag_from_filetype(session, new_file.type)) asset = session.query(Asset).filter(Asset.files.contains(new_file)).first() if asset is None: asset = Asset("auto_%s" % new_file.name, tags) asset.files.append(new_file) session.add(asset) else: raise Exception("Node type %s not handled" % info.kind) session.commit()
def create_rev_entry(rev_path, session, rev=None): """string, Session -> None Generate a database entry. """ if rev_path == u'': rev_path = u'.' if not os.path.exists(rev_path): return if rev is not None: xml_string = call_svn_cmd(rev_path, "info", "--incremental --xml -r %s" % rev.id) else: xml_string = call_svn_cmd(rev_path, "info", "--incremental --xml") svn = parse_svn(xml_string) if rev is None: revision = get_create_revision(rev_path, session, svn.revision) else: revision = rev if revision is None: return if svn.kind == u"file": old_file = session.query(File).get(unicode(rev_path)) if old_file is not None: old_file.size = os.path.getsize(rev_path) old_file.revision = revision parent = old_file.directory while parent is not None: parent.revision = revision session.add(parent) parent = parent.parent session.add(old_file) return new_file = File(rev_path, os.path.basename(rev_path), os.path.getsize(rev_path), svn.root) new_file.revision = revision session.add(new_file) parent_path = os.path.dirname(rev_path) if parent_path == u'': parent_path = u'.' parent_dir = session.query(Dir).get(parent_path) if parent_dir is None: # Parent directory was probably created in the same commit. # Recurse just to make sure the parent dir exits. This is # sub-optimal performance-wise, but keeps the database consistent. # SVN XML sucks. create_rev_entry(parent_path, session, rev) parent_dir = session.query(Dir).get(parent_path) new_file.directory = parent_dir session.add(new_file) tags = [] tags.append(get_tag_from_path(session, new_file.path)) tags.append(get_tag_from_filetype(session, new_file.type)) asset = session.query(Asset).filter(Asset.files.contains(new_file)).first() if asset is None: asset = Asset("auto_%s" % new_file.name, tags) asset.files.append(new_file) session.add(asset) elif svn.kind == u"dir": old_dir = session.query(Dir).get(unicode(rev_path)) if old_dir is not None: old_dir.revision = revision session.add(revision) return if rev_path != u'.': dir_name = os.path.basename(rev_path) else: dir_name = u'/' new_dir = Dir(rev_path, dir_name, svn.root) new_dir.revision = revision parent_path = os.path.dirname(rev_path) if parent_path == u'': parent_path = u'.' parent_dir = session.query(Dir).get(parent_path) if parent_dir is not None and rev_path != u'.': new_dir.parent = parent_dir session.add(new_dir)