Created
February 13, 2012 14:04
-
-
Save zerebubuth/1817152 to your computer and use it in GitHub Desktop.
Pseudo-ruby for ODbL change "bot"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Cleaner | |
def is_clean?(obj) | |
# objects tagged odbl=clean are defined as clean by the user, so | |
# we take this version as definitively clean, regardless of any | |
# prior history. | |
if obj.has_tag? "odbl" => "clean" | |
return true | |
else | |
# otherwise, this version is clean if and only if the previous | |
# version is clean (or this is the first version) *AND* the | |
# user (or adoptive user) who edited this object has agreed. | |
if obj.is_first_version? or is_clean?(obj.previous_version) | |
cs = obj.changeset | |
return cs.user.accepted_cts? or cs.adopted_user.accepted_cts? | |
else | |
# last chance for an object to be clean is if retains no | |
# information since the last dirty version. | |
dirty_version = obj | |
dirty_version = dirty_version.previuos_version while is_clean?(dirty_version) | |
return is_harmless?(dirty_version) | |
end | |
end | |
end | |
def is_harmless?(obj, dirty_obj) | |
# if the dirty version is a node move less than 1m and the previous | |
# version is clean, then this is a harmless edit. | |
if is_clean?(dirty_obj.previous_version) | |
if obj.is_node? and distance(dirty_obj, dirty_obj.previous_version) < 1m | |
return true | |
end | |
end | |
# if the tags on the current object include some of the keys | |
# used in the dirty version, then the object cannot be clean | |
if obj.tags.keys.any? {|k| dirty_obj.tags.has_key? k} | |
return false | |
end | |
case obj.type | |
when :node | |
# if the current object is a node and has been moved since the | |
# last dirty version then it's clean | |
if distance(obj, dirty_obj) > 0 | |
return true | |
end | |
when :way | |
# if the current object contains none of the nds used in | |
# the dirty object then it's clean. | |
if not obj.nds.any? {|n| dirty_obj.nds.include? n} | |
return true | |
end | |
when :relation | |
# ??? | |
end | |
return false | |
end | |
def action_to_clean(type, id, objects_to_delete) | |
obj_versions = @db.get_all_versions(type, id) | |
current_version = obj_versions.last | |
dirty_versions = obj_versions.select {|o| not is_clean?(o)} | |
if not is_clean?(current_version) | |
clean_versions = obj_versions.select {|o| is_clean?(o)} | |
if clean_versions.empty? | |
# no clean versions - we must delete this object | |
# and redact all versions of it. it might not be | |
# possible to delete the object right now, as it | |
# may be used in other objects - if so, then defer | |
# that action for later. | |
if is_used?(type, id) | |
@objects_to_delete << [type, id] | |
else | |
delete(type, id) | |
obj_versions.each {|o| redact(o)} | |
end | |
else | |
# some clean versions, so revert to the latest | |
# of these and redact all others. | |
revert(type, id, clean_versions.last) | |
dirty_versions.each {|o| redact(o)} | |
end | |
else | |
# current version is clean, so just need to redact | |
# any dirty previous versions. | |
dirty_versions.each {|o| redact(o)} | |
end | |
end | |
def clean | |
@objects_to_delete = [] | |
# clean all the objects we can at this point | |
@db.all_objects do |type, id| | |
action_to_clean(type, id) | |
end | |
# now just left with things to delete - which may | |
# require that we modify some other objects. | |
objs_to_modify = {} | |
@objects_to_delete.each do |type, id| | |
dependents(type, id).each do |d_type, d_id| | |
objs_to_modify[d_type, d_id] << [type, id] | |
end | |
end | |
objs_to_modify.each do |d_type, d_id| | |
# remove references to values in key | |
end | |
@objects_to_delete.each do |type, id| | |
obj_versions = @db.get_all_versions(type, id) | |
delete(type, id) | |
obj_versions.each {|o| redact(o)} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment