Skip to content

Instantly share code, notes, and snippets.

@camthesaxman
Last active June 10, 2018 23:33
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 camthesaxman/5142d293fddd877b6ba521075441ac83 to your computer and use it in GitHub Desktop.
Save camthesaxman/5142d293fddd877b6ba521075441ac83 to your computer and use it in GitHub Desktop.
pokeruby/pokeemerald diffing tool
#!/usr/bin/python
import BaseHTTPServer
import SocketServer
import difflib
import os
pageHeader = '''
<html>
<head>
<title>pretdiff</title>
<style>
table {
font-family:monospace;
font-smooth:never;
border-spacing:0;
white-space:pre;
border:1px solid;
}
table td:last-child {
border-left: 1px solid #000;
}
.emerald { background-color:#A0FFA0; }
.ruby { background-color:#FFA0A0; }
.info { background-color:#808080; color:#FFFFFF; }
</style>
</head>
<body>
<h1>pretdiff</h1>
'''
pageFooter= '''
</body>
</html>
'''
def read_range_info(string):
minus = string.find('-')
space1 = string.find(' ', minus)
plus = string.find('+')
space2 = string.find(' ', plus)
(start1, length1) = string[minus+1:space1].split(',')
(start2, length2) = string[plus+1:space2].split(',')
return (int(start1), int(length1), int(start2), int(length2))
def table_row(items, klass=None):
html = '<tr class="' + klass + '">' if (klass != None) else '<tr>'
for i in items:
html += '<td>' + str(i) + '</td>'
html += '</tr>\n'
return html
def make_table(difflines):
linenum1 = 1
linenum2 = 1
html = '<table>\n'
for line in difflines:
# Skip header
if line[:3] == '---' or line[:3] == '+++':
continue
if line[0] == '@' and line[1] == '@':
info = read_range_info(line)
linenum1 = info[0]
linenum2 = info[2]
html += table_row(['', '', line], 'info')
# Ruby line
elif line[0] == '-':
html += table_row([linenum1, '', line[1:]], 'ruby')
linenum1 += 1
# Emerald line
elif line[0] == '+':
html += table_row(['', linenum2, line[1:]], 'emerald')
linenum2 += 1
# Common line
else:
html += table_row([linenum1, linenum2, line[1:]], None)
linenum1 += 1
linenum2 += 1
html += '</table>\n'
return html
def generate_diff(filename):
with open('pokeruby/' + filename) as f:
rubyLines = f.read().splitlines()
with open('pokeemerald/' + filename) as f:
emeraldLines = f.read().splitlines()
difflines = difflib.unified_diff(rubyLines, emeraldLines)
return make_table(difflines)
def calc_file_stats(filename):
rubydiff = 0
emeralddiff = 0
with open('pokeruby/' + filename) as f:
rubyLines = f.read().splitlines()
with open('pokeemerald/' + filename) as f:
emeraldLines = f.read().splitlines()
difflines = difflib.unified_diff(rubyLines, emeraldLines)
for line in difflines:
# Skip header
if line[:3] == '---' or line[:3] == '+++':
continue
if line[0] == '-':
rubydiff += 1
elif line[0] == '+':
emeralddiff += 1
return (rubydiff, emeralddiff)
def link(text, url):
return '<a href="' + url + '">' + text + '</a>'
def generate_file_browser(directory):
# add trailing slash
if directory != '/':
directory += '/'
rbfiles = set(os.listdir('pokeruby/' + directory))
emfiles = set(os.listdir('pokeemerald/' + directory))
commonfiles = rbfiles.intersection(emfiles)
html = '<table border="1">\n'
html += '<th>filename</th><th>Ruby</th><th>Emerald</th>\n'
# common files
for f in sorted(commonfiles):
path = directory + f
html += '<tr>'
if os.path.isfile('pokeruby/' + path):
stats = calc_file_stats(path)
html += table_row([link(f, path), str(stats[0]), str(stats[1])])
else:
html += table_row([link(f, path)])
html += '</tr>'
# ruby-only files
for f in sorted(rbfiles.difference(commonfiles)):
html += table_row([f], 'ruby')
# emerald-only files
for f in sorted(emfiles.difference(commonfiles)):
html += table_row([f], 'emerald')
html += '</table>\n'
return html
def generate_navbar(path):
items = path.split('/')
html = '<p>'
html += link('root', '/')
linkpath = ''
for i in items:
if i != '':
linkpath += '/' + i
html += ' / ' + link(i, linkpath)
html += '</p>\n'
return html
def generate_errmsg(text):
html = '<p style="color:red">Error: ' + text + '</p><br>'
return html
class MyRequestHandlers(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
exists = True
page = pageHeader
page += generate_navbar(self.path)
# assuming it's the same for both
full = 'pokeruby' + self.path
if os.path.isfile(full):
page += generate_diff(self.path)
self.send_response(200)
elif os.path.isdir(full):
page += generate_file_browser(self.path)
self.send_response(200)
else:
page += generate_errmsg(self.path + ' was not found.')
self.send_response(404)
page += pageFooter
self.end_headers()
self.wfile.write(page)
for d in ['pokeruby', 'pokeemerald']:
if not os.path.isdir(d):
print(d + ' not found. Please clone it in the directory of this script')
sys.exit(1)
print('open http://localhost:8080 in your web browser')
SocketServer.TCPServer.allow_reuse_address = True
server = SocketServer.TCPServer(('', 8080), MyRequestHandlers)
server.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment