from __future__ import print_function from random import choice import string, sys, __builtin__ import itertools as it # <> def dp(*args): if DEBUG: print(*args) def uniques(lst): '''generator wich return each occurence only once : if an element is present more than once, it will be yield only the first time it is encountered''' seen=set() seen_add=seen.add for e in lst: if e not in seen: seen_add(e) yield e def wordisspecial(word): ''' tells if the word match this pattern : __xxx__ return True | False''' if (word[:2]==word[-2:]=='__') and (False not in map(lambda x: x.isalpha(), word[2:-2])): return True return False def trans(txt): return string.translate(txt,tbl) def ident(txt): '''return str(the identation of txt)''' return (len(txt.rstrip())-len(txt.strip()))*' ' def bazard(txt): '''a shuffling function''' l=len(txt) res='' idx=range(l) for x in xrange(l): r=choice(idx) idx.remove(r) res+=txt[r] return res def extract(txt): '''extract all the words from the text''' res='' for char in txt: if char.isalnum() or char=='_': res+=char else : res+=' ' return res.split() def iscomment(txt): '''Is the txt a comment ? True | False''' if txt.strip().startswith('#'): return True return False class Import(object): @staticmethod def isimport(txt): t=txt.strip() if t.startswith('from') or t.startswith('import'): return True return False @staticmethod def isfromform(txt): if txt.strip().startswith('from'): return True return False @staticmethod def isasin(txt): if ' as ' in txt: return True return False @staticmethod def ismodules(txt): if not Import.isfromform(txt): return True return False @staticmethod def extractimports(txt): r=extract(txt) s=r.index('import')+1 e=(r.index('as') if 'as' in r else len(r)-1) return r[s:e] @staticmethod def extractafteras(txt): r=extract(txt) return r[r.index('as')+1] @staticmethod def extractfrom(txt): r=extract(txt) return r[r.index('from')+1] # -- end -- <> DEBUG = False filename_in = sys.argv[1] filename_out = sys.argv[2] letters_org = string.ascii_letters letters_uorg = bazard(letters_org) tbl = string.maketrans(letters_org, letters_uorg) statements = 'and as assert break class continue def del elif else except exec finnaly for from global if import in is lambda not or pass print raise return try while with yield'.split() forbidden = statements[:]+dir(__builtin__)+dir(str)+dir(file)+dir([])+dir(set)+dir((1,))+dir({})+dir(frozenset) forbidden = list(uniques(forbidden)) translates = {} f_in = open(filename_in,'r') f_out = open(filename_out, 'w') for line in f_in: #import ? dp(line) if not iscomment(line): if Import.isimport(line): if Import.isasin(line): # << replace word next to as >> w=extract(line) i=w.index(Import.extractafteras(line)) if w[i] not in translates: translates[w[i]]=w[i]=trans(w[i]) else: w[i]=translates[w[i]] line=ident(line)+' '.join(w)+'\n' # -- end -- << replace word next to as >> if not Import.isfromform(line): # << forbid modules content not from>> lst=Import.extractimports(line) for module in lst: exec('import %s'%module) forbidden+=dir(eval(module)) # -- end -- << forbid modules content not from>> else: # << forbid import contents >> lst=Import.extractimports(line) _from=Import.extractfrom(line) for module in lst: exec('from %s import %s'%(_from,module)) forbidden+=dir(eval(module)) # -- end -- << forbid import contents >> else: # << forbid import names >> lst=Import.extractimports(line) forbidden+=lst # -- end -- << forbid import names >> if not Import.isfromform(line): # <> lst=Import.extractimports(line) for module in lst: exec('import %s'%module) forbidden+=dir(eval(module)) # -- end -- <> else: # << forbid import contents>> lst=Import.extractimports(line) _from=Import.extractfrom(line) for module in lst: exec('from %s import %s'%(_from,module)) forbidden+=dir(eval(module)) # -- end -- << forbid import contents>> else: dp('replace all words translatable...') # << replace all words translatable >> lst=extract(line) to_trans=[] txt='%s:\n\tforbiden ? %s\n\tspecial ? %s' for word in lst: dp(txt%(word, word in forbidden, wordisspecial(word))) if word not in forbidden and not wordisspecial(word): to_trans+=[word] if word not in translates: translates[word]=trans(word) for word in uniques(to_trans): s=0 l=len(word) while 1: try: i=line.index(word,s) s=i+l if not line[i-1].isalnum() and not line[s].isalnum() and '_' not in (line[i-1],line[s]): line=line[:i]+translates[word]+line[i+l:] except: break # -- end -- << replace all words translatable >> f_out.write(line) dp(line+'\n\n')