Sharedwww / app / jobs.pyOpen in CoCalc
Author: William A. Stein
1
import manin.misc.db as db
2
import os
3
4
def pad_number(i,max=100):
5
x = str(i)
6
n = len(str(max))
7
while len(x) < n:
8
x = " " + x
9
return x
10
11
class Note:
12
def note(self, x=None):
13
if x==None:
14
try:
15
return self.__note
16
except:
17
self.__note = ""
18
return ""
19
self.__note = self.note() + "\n" + x
20
def reset_note(self):
21
self.__note = ""
22
23
class Contact(Note):
24
"""
25
Helpful person relevant to getting a job somewhere.
26
"""
27
28
def __init__(self, name):
29
self.__name = name
30
31
def __repr__(self):
32
return self.__name
33
34
def email(self, address=None):
35
if address == None:
36
try:
37
return self.__email
38
except:
39
self.__email = ""
40
return ""
41
else:
42
self.__email = address
43
44
def indent(x, mark=""):
45
s = "\n\t%4s "%mark
46
return s + s.join(x.split("\n"))
47
48
class App(Note):
49
"""
50
Job application.
51
"""
52
53
def __init__(self, name):
54
self.__name = name
55
self.__rating = 0
56
57
def __repr__(self):
58
return "\n%s\nContacts: %s\nWant: %s\nAddress: %s\nNotes: %s\nStatus: %s"%(
59
self.summary().upper(), ", ".join([str(x) for x in self.contacts()]),
60
indent(self.want(),"*"), indent(self.address()),
61
indent(self.note(),"*"), indent(self.status(), "*"))
62
63
def __cmp__(self, x):
64
if not isinstance(x, App):
65
return -1
66
if self.__rating > x.__rating:
67
return -1
68
elif self.__rating < x.__rating:
69
return +1
70
elif self.__name < x.__name:
71
return -1
72
elif self.__name > x.__name:
73
return +1
74
return 0
75
76
def summary(self):
77
try:
78
_ = self.__address
79
address=""
80
except:
81
address="\t (no address)"
82
return "%s (%s) %s"%(self.__name, self.__rating, address)
83
84
def rename(self, new_name):
85
self.__name = new_name
86
87
def name(self, x=None):
88
if x != None:
89
self.__name = x
90
else:
91
return self.__name
92
93
def rating(self, r=None):
94
if r == None:
95
return self.__rating
96
else:
97
self.__rating = r
98
99
def contacts(self):
100
try:
101
return self.__contacts
102
except:
103
self.__contacts = []
104
return self.__contacts
105
106
def contact(self, n=None):
107
if n==None: return self.contacts()
108
return self.contacts()[n]
109
110
111
def address(self, *x):
112
if len(x)==0:
113
try:
114
return self.__address
115
except:
116
return "No address defined."
117
self.__address = "\n".join(x)
118
119
def label(self):
120
"""
121
A label consists of exactly six lines, each terminated
122
by two backslashes. Also any #'s and &'s are prefixed by
123
a backslashes.
124
"""
125
A = self.address().split("\n")
126
while len(A) < 6:
127
A.append("")
128
s = ""
129
for i in range(6):
130
s += A[i] + "\\mbox{}\\\\\n"
131
s = s.replace("#","\#")
132
s = s.replace("&","\&")
133
return s
134
135
def want(self, *x):
136
if len(x)==0:
137
try:
138
return self.__want
139
except:
140
return "Nothing listed yet."
141
self.__want = "\n".join(x)
142
143
def status(self, *x):
144
if len(x)==0:
145
try:
146
return self.__status
147
except:
148
return "Nothing entered."
149
try:
150
self.__status += "\n"+"\n".join(x)
151
except:
152
self.__status = "\n".join(x)
153
154
155
156
class Apps:
157
"""
158
Job applications package.
159
"""
160
161
def __init__(self):
162
self.__apps = []
163
164
def __repr__(self):
165
self.sort()
166
if len(self.__apps) == 0:
167
return "No applications yet."
168
s = ""
169
for i in range(len(self.__apps)):
170
s += "\ta[%s] %s\n"%(pad_number(i,len(self.__apps)),
171
self.__apps[i].summary())
172
return s
173
174
def sort(self):
175
self.__apps.sort()
176
177
def append(self,app):
178
if isinstance(app,list):
179
for x in app:
180
self.append(x)
181
return
182
if isinstance(app,str):
183
app = App(app)
184
assert isinstance(app, App)
185
self.__apps.append(app)
186
self.sort()
187
188
def __getitem__(self,n):
189
if isinstance(n,str):
190
n = n.lower()
191
for a in self.__apps:
192
if a.name().lower().find(n) != -1:
193
return a
194
raise IndexError, "The string appears in no job apps."
195
return self.__apps[n]
196
197
def __call__(self, n=None):
198
if n == None:
199
return str(self)
200
return self[n]
201
202
def __delitem__(self,n):
203
del self.__apps[n]
204
205
def __setitem__(self, n, app):
206
assert isinstance(app, App)
207
self.__apps[n] = app
208
self.sort()
209
210
def recommenders(self):
211
try:
212
return self.__recommenders
213
except:
214
self.__recommenders = []
215
return self.__recommenders
216
217
def cv(self):
218
os.system("cd /home/was/job/cv/; t 1>/dev/null 2>/dev/null&")
219
220
def research(self):
221
os.system("cd /home/was/job/research/; t 1>/dev/null 2>/dev/null&")
222
223
def teach(self):
224
os.system("cd /home/was/job/teach/; t 1>/dev/null 2>/dev/null&")
225
226
def works(self):
227
os.system("cd /home/was/job/works/; t 1>/dev/null 2>/dev/null&")
228
229
def contacts(self):
230
return "\n\t" + "\n\t".join([x.name() + " - " + str(x.contacts())
231
for x in self.__apps])
232
233
234
######################################################
235
236
DATA = "/home/was/job/data/apps.data"
237
if os.path.exists(DATA):
238
x = db.load(DATA)
239
apps = x[0]
240
else:
241
apps = Apps()
242
apps.sort()
243
print "\n"*3, "-"*80, "\n", apps
244
245
def save():
246
if not os.path.exists("/home/was/job/data/"):
247
os.makedirs("/home/was/job/data/")
248
db.save([apps], DATA)
249
250
def backup():
251
print "backing up"
252
os.system("cd /home/was/job/; archive job data 1>/dev/null 2>/dev/null&")
253
254
a = apps
255
s = save
256
b = backup
257
258
######################################################
259
def prefilter_paste(self, line, continuation):
260
"""
261
Alternate prefilter for input.
262
"""
263
from re import match
264
from IPython.iplib import InteractiveShell
265
266
if not continuation:
267
if line=="quit" or line=="q":
268
eval("save()")
269
#InteractiveShell._prefilter(self, "save()", continuation)
270
line = "%Quit"
271
return InteractiveShell._prefilter(self, line, continuation)
272
273
# Rebind this to be the new IPython prefilter:
274
from IPython.iplib import InteractiveShell
275
InteractiveShell.prefilter = prefilter_paste
276
# Clean up the namespace.
277
del InteractiveShell,prefilter_paste
278
######################################################
279
280
281
282
def generate_labels(A):
283
# first generate Irene's labels
284
irene = open("labels/addresses.tex","w")
285
def emit(j, who):
286
irene.write("\\address{%s}{%s}"%(A[i].label(),who))
287
if j%2==1:
288
irene.write("\\\\")
289
irene.write("\n")
290
if j%6==5:
291
irene.write("\n\\newpage\\mbox{}\\vspace{0.5cm}\\par\\noindent\n")
292
j=0
293
for i in range(len(A)):
294
emit(j,"Irene Minder")
295
j += 1
296
emit(j,"William Stein")
297
j += 1
298
299
300
def cover_letters(A):
301
form = open("cover/cover.tex").read()
302
for j in range(len(A)):
303
a = A[j]
304
letter = str(form)
305
c = [str(t) for t in a.contacts() if str(t).find("DSSG") == -1]
306
if len(c) == 0:
307
phrase = ""
308
else:
309
phrase = "In your department, my research is closest to that of "
310
for i in range(len(c)):
311
phrase += c[i]
312
if len(c)==2:
313
if i==0:
314
phrase += " and "
315
else:
316
if i <= len(c)-3:
317
phrase += ", "
318
elif i == len(c)-2:
319
phrase += ", and "
320
phrase += "."
321
letter = letter.replace("%My research is closest to that of ...", phrase)
322
letter = letter.replace("%TO",a.label())
323
filename = "cover/letters/%s.tex"%j
324
open(filename,"w").write(letter)
325
os.system("cd cover/letters/; latex %s.tex "%j)
326
327