-
Notifications
You must be signed in to change notification settings - Fork 0
/
FakeDataGenerator.py
executable file
·160 lines (130 loc) · 4.25 KB
/
FakeDataGenerator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import re, os, sys
import sublime
import sublime_plugin
# global settings container
s = {}
Pref = {}
faker = {}
debug = False
class Pref:
def load(self):
Pref.seed = s.get('seed', 'yep')
Pref.locale = s.get('locale', 'en_GB')
class FakeDataGenerator(sublime_plugin.TextCommand):
def run(self, edit):
if debug:
self.on_done(1)
else:
Window().run_command('hide_panel');
view = Window().show_input_panel("Repeat:", "1", self.on_done, None, None)
view.sel().clear()
view.sel().add(sublime.Region(0, view.size()))
def on_done(self, repeat):
global faker
repeat = int(repeat or 0)
if repeat>0:
view = View()
faker = self._faker()
if Pref.seed:
faker.seed(Pref.seed)
def index(_counter_index = -1):
if not _counter_index in index.counter:
index.counter[_counter_index] = -1
index.counter[_counter_index]+=1
return index.counter[_counter_index]
index.counter = {}; faker.index = index;
try:
from .Edit import Edit as Edit
except:
from Edit import Edit as Edit
with Edit(view) as edit:
for region in reversed(view.sel()):
if region.empty():
continue
content = view.substr(region)*repeat
functions_and_modifiers = re.findall('{{(.*?)(\|[^}]+)?}}', content, re.U | re.I)
for function, modifiers in functions_and_modifiers:
find_for = str('{{'+function+modifiers+'}}')
modifiers = modifiers.split('|'); modifiers.pop(0)
callable = lambda:self.value(lambda:eval('faker.'+function))
value = None
if not modifiers:
try:
value = callable()
except Exception as e:
print('FakeDataGenerator: Error evaluating faker expression "'+function+'" : '+ str(e).strip())
else:
for modifier in modifiers:
if not value:
# the first modifier receive the faker object, and may whish to call it multiple times.
pass
else:
# faker object already applied, just send the value
callable = lambda:self._return(value)
try:
value = eval('self.'+(modifier.replace('(', '(callable,', 1)))
except Exception as e:
print('FakeDataGenerator: Error evaluating modifier expression "'+modifier+'", or faker expression : '+ str(e).strip())
content = content.replace(find_for, value, 1)
edit.replace(region, content)
# normalize a value from faker
def normalize(self, value):
return str(value).replace('True', 'true').replace('False', 'false').replace('None', 'null')
def value(self, value):
_value = value()
if type(_value) is list:
return self.normalize(' '.join(_value))
else:
return self.normalize(_value)
# modifiers
def repeat(self, callable, nTimes = 1, separator = ','):
value = []
if type(nTimes) is tuple:
import random
random.seed()
nTimes = random.randint(nTimes[0], nTimes[1])
for i in range(0, int(str(nTimes))):
value.append(callable())
return separator.join(value)
def encode(self, callable):
try:
from urllib import quote as urlquote
except ImportError:
from urllib.parse import quote as urlquote
return urlquote(callable().encode('utf8'), '')
def escape(self, callable):
return callable().encode('ascii', 'backslashreplace').decode('utf-8')
# utils
def _faker(self):
Faker = self._import_path(os.path.dirname(__file__)+'/faker/faker')
return Faker.Factory.create(Pref.locale)
def _import_path(self, fullpath):
"""
Import a file with full path specification. Allows one to
import from anywhere, something __import__ does not do.
"""
path, filename = os.path.split(fullpath)
filename, ext = os.path.splitext(filename)
sys.path.append(path)
module = __import__(filename)
#reload(module) # Might be out of date
sys.path.remove(path)
return module
def _return(self, value):
return value
class FakeDataGeneratorInsert(sublime_plugin.TextCommand):
def run(self, edit, content):
view = View()
view.run_command('insert', {'characters': '{{'+content+'}}'})
def Window():
return sublime.active_window()
def View():
return Window().active_view()
def plugin_loaded():
global s, Pref
s = sublime.load_settings('FakeDataGenerator.sublime-settings')
Pref = Pref()
Pref.load()
s.add_on_change('reload_prefs', lambda:Pref.load())
if int(sublime.version()) < 3000:
plugin_loaded()