Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
72dc60ca
Kaydet (Commit)
72dc60ca
authored
Nis 06, 1998
tarafından
Guido van Rossum
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Untabified, for tabnanny.
üst
e4e41062
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
593 additions
and
593 deletions
+593
-593
faqwiz.py
Tools/faqwiz/faqwiz.py
+593
-593
No files found.
Tools/faqwiz/faqwiz.py
Dosyayı görüntüle @
72dc60ca
...
...
@@ -12,25 +12,25 @@ The actual script to place in cgi-bin is faqw.py.
"""
import
sys
,
string
,
time
,
os
,
stat
,
re
,
cgi
,
faqconf
from
faqconf
import
*
# This imports all uppercase names
from
faqconf
import
*
# This imports all uppercase names
now
=
time
.
time
()
class
FileError
:
def
__init__
(
self
,
file
):
self
.
file
=
file
self
.
file
=
file
class
InvalidFile
(
FileError
):
pass
class
NoSuchSection
(
FileError
):
def
__init__
(
self
,
section
):
FileError
.
__init__
(
self
,
NEWFILENAME
%
(
section
,
1
))
self
.
section
=
section
FileError
.
__init__
(
self
,
NEWFILENAME
%
(
section
,
1
))
self
.
section
=
section
class
NoSuchFile
(
FileError
):
def
__init__
(
self
,
file
,
why
=
None
):
FileError
.
__init__
(
self
,
file
)
self
.
why
=
why
FileError
.
__init__
(
self
,
file
)
self
.
why
=
why
def
escape
(
s
):
s
=
string
.
replace
(
s
,
'&'
,
'&'
)
...
...
@@ -45,9 +45,9 @@ def escapeq(s):
def
_interpolate
(
format
,
args
,
kw
):
try
:
quote
=
kw
[
'_quote'
]
quote
=
kw
[
'_quote'
]
except
KeyError
:
quote
=
1
quote
=
1
d
=
(
kw
,)
+
args
+
(
faqconf
.
__dict__
,)
m
=
MagicDict
(
d
,
quote
)
return
format
%
m
...
...
@@ -57,9 +57,9 @@ def interpolate(format, *args, **kw):
def
emit
(
format
,
*
args
,
**
kw
):
try
:
f
=
kw
[
'_file'
]
f
=
kw
[
'_file'
]
except
KeyError
:
f
=
sys
.
stdout
f
=
sys
.
stdout
f
.
write
(
_interpolate
(
format
,
args
,
kw
))
translate_prog
=
None
...
...
@@ -67,32 +67,32 @@ translate_prog = None
def
translate
(
text
,
pre
=
0
):
global
translate_prog
if
not
translate_prog
:
translate_prog
=
prog
=
re
.
compile
(
r'\b(http|ftp|https)://\S+(\b|/)|\b[-.\w]+@[-.\w]+'
)
translate_prog
=
prog
=
re
.
compile
(
r'\b(http|ftp|https)://\S+(\b|/)|\b[-.\w]+@[-.\w]+'
)
else
:
prog
=
translate_prog
prog
=
translate_prog
i
=
0
list
=
[]
while
1
:
m
=
prog
.
search
(
text
,
i
)
if
not
m
:
break
j
=
m
.
start
()
list
.
append
(
escape
(
text
[
i
:
j
]))
i
=
j
url
=
m
.
group
(
0
)
while
url
[
-
1
]
in
'();:,.?
\'
"<>'
:
url
=
url
[:
-
1
]
i
=
i
+
len
(
url
)
url
=
escape
(
url
)
if
not
pre
or
(
pre
and
PROCESS_PREFORMAT
):
if
':'
in
url
:
repl
=
'<A HREF="
%
s">
%
s</A>'
%
(
url
,
url
)
else
:
repl
=
'<A HREF="mailto:
%
s"><
%
s></A>'
%
(
url
,
url
)
else
:
repl
=
url
list
.
append
(
repl
)
m
=
prog
.
search
(
text
,
i
)
if
not
m
:
break
j
=
m
.
start
()
list
.
append
(
escape
(
text
[
i
:
j
]))
i
=
j
url
=
m
.
group
(
0
)
while
url
[
-
1
]
in
'();:,.?
\'
"<>'
:
url
=
url
[:
-
1
]
i
=
i
+
len
(
url
)
url
=
escape
(
url
)
if
not
pre
or
(
pre
and
PROCESS_PREFORMAT
):
if
':'
in
url
:
repl
=
'<A HREF="
%
s">
%
s</A>'
%
(
url
,
url
)
else
:
repl
=
'<A HREF="mailto:
%
s"><
%
s></A>'
%
(
url
,
url
)
else
:
repl
=
url
list
.
append
(
repl
)
j
=
len
(
text
)
list
.
append
(
escape
(
text
[
i
:
j
]))
return
string
.
join
(
list
,
''
)
...
...
@@ -105,43 +105,43 @@ revparse_prog = None
def
revparse
(
rev
):
global
revparse_prog
if
not
revparse_prog
:
revparse_prog
=
re
.
compile
(
r'^(\d{1,3})\.(\d{1-4})$'
)
revparse_prog
=
re
.
compile
(
r'^(\d{1,3})\.(\d{1-4})$'
)
m
=
revparse_prog
.
match
(
rev
)
if
not
m
:
return
None
return
None
[
major
,
minor
]
=
map
(
string
.
atoi
,
m
.
group
(
1
,
2
))
return
major
,
minor
def
load_cookies
():
if
not
os
.
environ
.
has_key
(
'HTTP_COOKIE'
):
return
{}
return
{}
raw
=
os
.
environ
[
'HTTP_COOKIE'
]
words
=
map
(
string
.
strip
,
string
.
split
(
raw
,
';'
))
cookies
=
{}
for
word
in
words
:
i
=
string
.
find
(
word
,
'='
)
if
i
>=
0
:
key
,
value
=
word
[:
i
],
word
[
i
+
1
:]
cookies
[
key
]
=
value
i
=
string
.
find
(
word
,
'='
)
if
i
>=
0
:
key
,
value
=
word
[:
i
],
word
[
i
+
1
:]
cookies
[
key
]
=
value
return
cookies
def
load_my_cookie
():
cookies
=
load_cookies
()
try
:
value
=
cookies
[
COOKIE_NAME
]
value
=
cookies
[
COOKIE_NAME
]
except
KeyError
:
return
{}
return
{}
import
urllib
value
=
urllib
.
unquote
(
value
)
words
=
string
.
split
(
value
,
'/'
)
while
len
(
words
)
<
3
:
words
.
append
(
''
)
words
.
append
(
''
)
author
=
string
.
join
(
words
[:
-
2
],
'/'
)
email
=
words
[
-
2
]
password
=
words
[
-
1
]
return
{
'author'
:
author
,
'email'
:
email
,
'password'
:
password
}
'email'
:
email
,
'password'
:
password
}
def
send_my_cookie
(
ui
):
name
=
COOKIE_NAME
...
...
@@ -156,147 +156,147 @@ def send_my_cookie(ui):
class
MagicDict
:
def
__init__
(
self
,
d
,
quote
):
self
.
__d
=
d
self
.
__quote
=
quote
self
.
__d
=
d
self
.
__quote
=
quote
def
__getitem__
(
self
,
key
):
for
d
in
self
.
__d
:
try
:
value
=
d
[
key
]
if
value
:
value
=
str
(
value
)
if
self
.
__quote
:
value
=
escapeq
(
value
)
return
value
except
KeyError
:
pass
return
''
for
d
in
self
.
__d
:
try
:
value
=
d
[
key
]
if
value
:
value
=
str
(
value
)
if
self
.
__quote
:
value
=
escapeq
(
value
)
return
value
except
KeyError
:
pass
return
''
class
UserInput
:
def
__init__
(
self
):
self
.
__form
=
cgi
.
FieldStorage
()
self
.
__form
=
cgi
.
FieldStorage
()
def
__getattr__
(
self
,
name
):
if
name
[
0
]
==
'_'
:
raise
AttributeError
try
:
value
=
self
.
__form
[
name
]
.
value
except
(
TypeError
,
KeyError
):
value
=
''
else
:
value
=
string
.
strip
(
value
)
setattr
(
self
,
name
,
value
)
return
value
if
name
[
0
]
==
'_'
:
raise
AttributeError
try
:
value
=
self
.
__form
[
name
]
.
value
except
(
TypeError
,
KeyError
):
value
=
''
else
:
value
=
string
.
strip
(
value
)
setattr
(
self
,
name
,
value
)
return
value
def
__getitem__
(
self
,
key
):
return
getattr
(
self
,
key
)
return
getattr
(
self
,
key
)
class
FaqEntry
:
def
__init__
(
self
,
fp
,
file
,
sec_num
):
self
.
file
=
file
self
.
sec
,
self
.
num
=
sec_num
if
fp
:
import
rfc822
self
.
__headers
=
rfc822
.
Message
(
fp
)
self
.
body
=
string
.
strip
(
fp
.
read
())
else
:
self
.
__headers
=
{
'title'
:
"
%
d.
%
d. "
%
sec_num
}
self
.
body
=
''
self
.
file
=
file
self
.
sec
,
self
.
num
=
sec_num
if
fp
:
import
rfc822
self
.
__headers
=
rfc822
.
Message
(
fp
)
self
.
body
=
string
.
strip
(
fp
.
read
())
else
:
self
.
__headers
=
{
'title'
:
"
%
d.
%
d. "
%
sec_num
}
self
.
body
=
''
def
__getattr__
(
self
,
name
):
if
name
[
0
]
==
'_'
:
raise
AttributeError
key
=
string
.
join
(
string
.
split
(
name
,
'_'
),
'-'
)
try
:
value
=
self
.
__headers
[
key
]
except
KeyError
:
value
=
''
setattr
(
self
,
name
,
value
)
return
value
if
name
[
0
]
==
'_'
:
raise
AttributeError
key
=
string
.
join
(
string
.
split
(
name
,
'_'
),
'-'
)
try
:
value
=
self
.
__headers
[
key
]
except
KeyError
:
value
=
''
setattr
(
self
,
name
,
value
)
return
value
def
__getitem__
(
self
,
key
):
return
getattr
(
self
,
key
)
return
getattr
(
self
,
key
)
def
load_version
(
self
):
command
=
interpolate
(
SH_RLOG_H
,
self
)
p
=
os
.
popen
(
command
)
version
=
''
while
1
:
line
=
p
.
readline
()
if
not
line
:
break
if
line
[:
5
]
==
'head:'
:
version
=
string
.
strip
(
line
[
5
:])
p
.
close
()
self
.
version
=
version
command
=
interpolate
(
SH_RLOG_H
,
self
)
p
=
os
.
popen
(
command
)
version
=
''
while
1
:
line
=
p
.
readline
()
if
not
line
:
break
if
line
[:
5
]
==
'head:'
:
version
=
string
.
strip
(
line
[
5
:])
p
.
close
()
self
.
version
=
version
def
getmtime
(
self
):
if
not
self
.
last_changed_date
:
return
0
try
:
return
os
.
stat
(
self
.
file
)[
stat
.
ST_MTIME
]
except
os
.
error
:
return
0
if
not
self
.
last_changed_date
:
return
0
try
:
return
os
.
stat
(
self
.
file
)[
stat
.
ST_MTIME
]
except
os
.
error
:
return
0
def
emit_marks
(
self
):
mtime
=
self
.
getmtime
()
if
mtime
>=
now
-
DT_VERY_RECENT
:
emit
(
MARK_VERY_RECENT
,
self
)
elif
mtime
>=
now
-
DT_RECENT
:
emit
(
MARK_RECENT
,
self
)
mtime
=
self
.
getmtime
()
if
mtime
>=
now
-
DT_VERY_RECENT
:
emit
(
MARK_VERY_RECENT
,
self
)
elif
mtime
>=
now
-
DT_RECENT
:
emit
(
MARK_RECENT
,
self
)
def
show
(
self
,
edit
=
1
):
emit
(
ENTRY_HEADER1
,
self
)
self
.
emit_marks
()
emit
(
ENTRY_HEADER2
,
self
)
pre
=
0
raw
=
0
for
line
in
string
.
split
(
self
.
body
,
'
\n
'
):
# Allow the user to insert raw html into a FAQ answer
# (Skip Montanaro, with changes by Guido)
tag
=
string
.
lower
(
string
.
rstrip
(
line
))
if
tag
==
'<html>'
:
raw
=
1
continue
if
tag
==
'</html>'
:
raw
=
0
continue
if
raw
:
print
line
continue
if
not
string
.
strip
(
line
):
if
pre
:
print
'</PRE>'
pre
=
0
else
:
print
'<P>'
else
:
if
line
[
0
]
not
in
string
.
whitespace
:
if
pre
:
print
'</PRE>'
pre
=
0
else
:
if
not
pre
:
print
'<PRE>'
pre
=
1
if
'/'
in
line
or
'@'
in
line
:
line
=
translate
(
line
,
pre
)
elif
'<'
in
line
or
'&'
in
line
:
line
=
escape
(
line
)
if
not
pre
and
'*'
in
line
:
line
=
emphasize
(
line
)
print
line
if
pre
:
print
'</PRE>'
pre
=
0
if
edit
:
print
'<P>'
emit
(
ENTRY_FOOTER
,
self
)
if
self
.
last_changed_date
:
emit
(
ENTRY_LOGINFO
,
self
)
print
'<P>'
emit
(
ENTRY_HEADER1
,
self
)
self
.
emit_marks
()
emit
(
ENTRY_HEADER2
,
self
)
pre
=
0
raw
=
0
for
line
in
string
.
split
(
self
.
body
,
'
\n
'
):
# Allow the user to insert raw html into a FAQ answer
# (Skip Montanaro, with changes by Guido)
tag
=
string
.
lower
(
string
.
rstrip
(
line
))
if
tag
==
'<html>'
:
raw
=
1
continue
if
tag
==
'</html>'
:
raw
=
0
continue
if
raw
:
print
line
continue
if
not
string
.
strip
(
line
):
if
pre
:
print
'</PRE>'
pre
=
0
else
:
print
'<P>'
else
:
if
line
[
0
]
not
in
string
.
whitespace
:
if
pre
:
print
'</PRE>'
pre
=
0
else
:
if
not
pre
:
print
'<PRE>'
pre
=
1
if
'/'
in
line
or
'@'
in
line
:
line
=
translate
(
line
,
pre
)
elif
'<'
in
line
or
'&'
in
line
:
line
=
escape
(
line
)
if
not
pre
and
'*'
in
line
:
line
=
emphasize
(
line
)
print
line
if
pre
:
print
'</PRE>'
pre
=
0
if
edit
:
print
'<P>'
emit
(
ENTRY_FOOTER
,
self
)
if
self
.
last_changed_date
:
emit
(
ENTRY_LOGINFO
,
self
)
print
'<P>'
class
FaqDir
:
...
...
@@ -305,517 +305,517 @@ class FaqDir:
__okprog
=
re
.
compile
(
OKFILENAME
)
def
__init__
(
self
,
dir
=
os
.
curdir
):
self
.
__dir
=
dir
self
.
__files
=
None
self
.
__dir
=
dir
self
.
__files
=
None
def
__fill
(
self
):
if
self
.
__files
is
not
None
:
return
self
.
__files
=
files
=
[]
okprog
=
self
.
__okprog
for
file
in
os
.
listdir
(
self
.
__dir
):
if
self
.
__okprog
.
match
(
file
):
files
.
append
(
file
)
files
.
sort
()
if
self
.
__files
is
not
None
:
return
self
.
__files
=
files
=
[]
okprog
=
self
.
__okprog
for
file
in
os
.
listdir
(
self
.
__dir
):
if
self
.
__okprog
.
match
(
file
):
files
.
append
(
file
)
files
.
sort
()
def
good
(
self
,
file
):
return
self
.
__okprog
.
match
(
file
)
return
self
.
__okprog
.
match
(
file
)
def
parse
(
self
,
file
):
m
=
self
.
good
(
file
)
if
not
m
:
return
None
sec
,
num
=
m
.
group
(
1
,
2
)
return
string
.
atoi
(
sec
),
string
.
atoi
(
num
)
m
=
self
.
good
(
file
)
if
not
m
:
return
None
sec
,
num
=
m
.
group
(
1
,
2
)
return
string
.
atoi
(
sec
),
string
.
atoi
(
num
)
def
list
(
self
):
# XXX Caller shouldn't modify result
self
.
__fill
()
return
self
.
__files
# XXX Caller shouldn't modify result
self
.
__fill
()
return
self
.
__files
def
open
(
self
,
file
):
sec_num
=
self
.
parse
(
file
)
if
not
sec_num
:
raise
InvalidFile
(
file
)
try
:
fp
=
open
(
file
)
except
IOError
,
msg
:
raise
NoSuchFile
(
file
,
msg
)
try
:
return
self
.
entryclass
(
fp
,
file
,
sec_num
)
finally
:
fp
.
close
()
sec_num
=
self
.
parse
(
file
)
if
not
sec_num
:
raise
InvalidFile
(
file
)
try
:
fp
=
open
(
file
)
except
IOError
,
msg
:
raise
NoSuchFile
(
file
,
msg
)
try
:
return
self
.
entryclass
(
fp
,
file
,
sec_num
)
finally
:
fp
.
close
()
def
show
(
self
,
file
,
edit
=
1
):
self
.
open
(
file
)
.
show
(
edit
=
edit
)
self
.
open
(
file
)
.
show
(
edit
=
edit
)
def
new
(
self
,
section
):
if
not
SECTION_TITLES
.
has_key
(
section
):
raise
NoSuchSection
(
section
)
maxnum
=
0
for
file
in
self
.
list
():
sec
,
num
=
self
.
parse
(
file
)
if
sec
==
section
:
maxnum
=
max
(
maxnum
,
num
)
sec_num
=
(
section
,
maxnum
+
1
)
file
=
NEWFILENAME
%
sec_num
return
self
.
entryclass
(
None
,
file
,
sec_num
)
if
not
SECTION_TITLES
.
has_key
(
section
):
raise
NoSuchSection
(
section
)
maxnum
=
0
for
file
in
self
.
list
():
sec
,
num
=
self
.
parse
(
file
)
if
sec
==
section
:
maxnum
=
max
(
maxnum
,
num
)
sec_num
=
(
section
,
maxnum
+
1
)
file
=
NEWFILENAME
%
sec_num
return
self
.
entryclass
(
None
,
file
,
sec_num
)
class
FaqWizard
:
def
__init__
(
self
):
self
.
ui
=
UserInput
()
self
.
dir
=
FaqDir
()
self
.
ui
=
UserInput
()
self
.
dir
=
FaqDir
()
def
go
(
self
):
print
'Content-type: text/html'
req
=
self
.
ui
.
req
or
'home'
mname
=
'do_
%
s'
%
req
try
:
meth
=
getattr
(
self
,
mname
)
except
AttributeError
:
self
.
error
(
"Bad request type
%
s."
%
`req`
)
else
:
try
:
meth
()
except
InvalidFile
,
exc
:
self
.
error
(
"Invalid entry file name
%
s"
%
exc
.
file
)
except
NoSuchFile
,
exc
:
self
.
error
(
"No entry with file name
%
s"
%
exc
.
file
)
except
NoSuchSection
,
exc
:
self
.
error
(
"No section number
%
s"
%
exc
.
section
)
self
.
epilogue
()
print
'Content-type: text/html'
req
=
self
.
ui
.
req
or
'home'
mname
=
'do_
%
s'
%
req
try
:
meth
=
getattr
(
self
,
mname
)
except
AttributeError
:
self
.
error
(
"Bad request type
%
s."
%
`req`
)
else
:
try
:
meth
()
except
InvalidFile
,
exc
:
self
.
error
(
"Invalid entry file name
%
s"
%
exc
.
file
)
except
NoSuchFile
,
exc
:
self
.
error
(
"No entry with file name
%
s"
%
exc
.
file
)
except
NoSuchSection
,
exc
:
self
.
error
(
"No section number
%
s"
%
exc
.
section
)
self
.
epilogue
()
def
error
(
self
,
message
,
**
kw
):
self
.
prologue
(
T_ERROR
)
emit
(
message
,
kw
)
self
.
prologue
(
T_ERROR
)
emit
(
message
,
kw
)
def
prologue
(
self
,
title
,
entry
=
None
,
**
kw
):
emit
(
PROLOGUE
,
entry
,
kwdict
=
kw
,
title
=
escape
(
title
))
emit
(
PROLOGUE
,
entry
,
kwdict
=
kw
,
title
=
escape
(
title
))
def
epilogue
(
self
):
emit
(
EPILOGUE
)
emit
(
EPILOGUE
)
def
do_home
(
self
):
self
.
prologue
(
T_HOME
)
emit
(
HOME
)
self
.
prologue
(
T_HOME
)
emit
(
HOME
)
def
do_debug
(
self
):
self
.
prologue
(
"FAQ Wizard Debugging"
)
form
=
cgi
.
FieldStorage
()
cgi
.
print_form
(
form
)
self
.
prologue
(
"FAQ Wizard Debugging"
)
form
=
cgi
.
FieldStorage
()
cgi
.
print_form
(
form
)
cgi
.
print_environ
(
os
.
environ
)
cgi
.
print_directory
()
cgi
.
print_arguments
()
cgi
.
print_directory
()
cgi
.
print_arguments
()
def
do_search
(
self
):
query
=
self
.
ui
.
query
if
not
query
:
self
.
error
(
"Empty query string!"
)
return
if
self
.
ui
.
querytype
==
'simple'
:
query
=
re
.
escape
(
query
)
queries
=
[
query
]
elif
self
.
ui
.
querytype
in
(
'anykeywords'
,
'allkeywords'
):
words
=
filter
(
None
,
re
.
split
(
'
\
W+'
,
query
))
if
not
words
:
self
.
error
(
"No keywords specified!"
)
return
words
=
map
(
lambda
w
:
r'\b
%
s\b'
%
w
,
words
)
if
self
.
ui
.
querytype
[:
3
]
==
'any'
:
queries
=
[
string
.
join
(
words
,
'|'
)]
else
:
# Each of the individual queries must match
queries
=
words
else
:
# Default to regular expression
queries
=
[
query
]
self
.
prologue
(
T_SEARCH
)
progs
=
[]
for
query
in
queries
:
if
self
.
ui
.
casefold
==
'no'
:
p
=
re
.
compile
(
query
)
else
:
p
=
re
.
compile
(
query
,
re
.
IGNORECASE
)
progs
.
append
(
p
)
hits
=
[]
for
file
in
self
.
dir
.
list
():
try
:
entry
=
self
.
dir
.
open
(
file
)
except
FileError
:
constants
for
p
in
progs
:
if
not
p
.
search
(
entry
.
title
)
and
not
p
.
search
(
entry
.
body
):
break
else
:
hits
.
append
(
file
)
if
not
hits
:
emit
(
NO_HITS
,
self
.
ui
,
count
=
0
)
elif
len
(
hits
)
<=
MAXHITS
:
if
len
(
hits
)
==
1
:
emit
(
ONE_HIT
,
count
=
1
)
else
:
emit
(
FEW_HITS
,
count
=
len
(
hits
))
self
.
format_all
(
hits
,
headers
=
0
)
else
:
emit
(
MANY_HITS
,
count
=
len
(
hits
))
self
.
format_index
(
hits
)
query
=
self
.
ui
.
query
if
not
query
:
self
.
error
(
"Empty query string!"
)
return
if
self
.
ui
.
querytype
==
'simple'
:
query
=
re
.
escape
(
query
)
queries
=
[
query
]
elif
self
.
ui
.
querytype
in
(
'anykeywords'
,
'allkeywords'
):
words
=
filter
(
None
,
re
.
split
(
'
\
W+'
,
query
))
if
not
words
:
self
.
error
(
"No keywords specified!"
)
return
words
=
map
(
lambda
w
:
r'\b
%
s\b'
%
w
,
words
)
if
self
.
ui
.
querytype
[:
3
]
==
'any'
:
queries
=
[
string
.
join
(
words
,
'|'
)]
else
:
# Each of the individual queries must match
queries
=
words
else
:
# Default to regular expression
queries
=
[
query
]
self
.
prologue
(
T_SEARCH
)
progs
=
[]
for
query
in
queries
:
if
self
.
ui
.
casefold
==
'no'
:
p
=
re
.
compile
(
query
)
else
:
p
=
re
.
compile
(
query
,
re
.
IGNORECASE
)
progs
.
append
(
p
)
hits
=
[]
for
file
in
self
.
dir
.
list
():
try
:
entry
=
self
.
dir
.
open
(
file
)
except
FileError
:
constants
for
p
in
progs
:
if
not
p
.
search
(
entry
.
title
)
and
not
p
.
search
(
entry
.
body
):
break
else
:
hits
.
append
(
file
)
if
not
hits
:
emit
(
NO_HITS
,
self
.
ui
,
count
=
0
)
elif
len
(
hits
)
<=
MAXHITS
:
if
len
(
hits
)
==
1
:
emit
(
ONE_HIT
,
count
=
1
)
else
:
emit
(
FEW_HITS
,
count
=
len
(
hits
))
self
.
format_all
(
hits
,
headers
=
0
)
else
:
emit
(
MANY_HITS
,
count
=
len
(
hits
))
self
.
format_index
(
hits
)
def
do_all
(
self
):
self
.
prologue
(
T_ALL
)
files
=
self
.
dir
.
list
()
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
localrefs
=
1
)
self
.
format_all
(
files
)
self
.
prologue
(
T_ALL
)
files
=
self
.
dir
.
list
()
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
localrefs
=
1
)
self
.
format_all
(
files
)
def
do_compat
(
self
):
files
=
self
.
dir
.
list
()
emit
(
COMPAT
)
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
localrefs
=
1
)
self
.
format_all
(
files
,
edit
=
0
)
sys
.
exit
(
0
)
# XXX Hack to suppress epilogue
files
=
self
.
dir
.
list
()
emit
(
COMPAT
)
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
localrefs
=
1
)
self
.
format_all
(
files
,
edit
=
0
)
sys
.
exit
(
0
)
# XXX Hack to suppress epilogue
def
last_changed
(
self
,
files
):
latest
=
0
for
file
in
files
:
entry
=
self
.
dir
.
open
(
file
)
if
entry
:
mtime
=
mtime
=
entry
.
getmtime
()
if
mtime
>
latest
:
latest
=
mtime
print
time
.
strftime
(
LAST_CHANGED
,
time
.
localtime
(
latest
))
emit
(
EXPLAIN_MARKS
)
latest
=
0
for
file
in
files
:
entry
=
self
.
dir
.
open
(
file
)
if
entry
:
mtime
=
mtime
=
entry
.
getmtime
()
if
mtime
>
latest
:
latest
=
mtime
print
time
.
strftime
(
LAST_CHANGED
,
time
.
localtime
(
latest
))
emit
(
EXPLAIN_MARKS
)
def
format_all
(
self
,
files
,
edit
=
1
,
headers
=
1
):
sec
=
0
for
file
in
files
:
try
:
entry
=
self
.
dir
.
open
(
file
)
except
NoSuchFile
:
continue
if
headers
and
entry
.
sec
!=
sec
:
sec
=
entry
.
sec
try
:
title
=
SECTION_TITLES
[
sec
]
except
KeyError
:
title
=
"Untitled"
emit
(
"
\n
<HR>
\n
<H1>
%(sec)
s.
%(title)
s</H1>
\n
"
,
sec
=
sec
,
title
=
title
)
entry
.
show
(
edit
=
edit
)
sec
=
0
for
file
in
files
:
try
:
entry
=
self
.
dir
.
open
(
file
)
except
NoSuchFile
:
continue
if
headers
and
entry
.
sec
!=
sec
:
sec
=
entry
.
sec
try
:
title
=
SECTION_TITLES
[
sec
]
except
KeyError
:
title
=
"Untitled"
emit
(
"
\n
<HR>
\n
<H1>
%(sec)
s.
%(title)
s</H1>
\n
"
,
sec
=
sec
,
title
=
title
)
entry
.
show
(
edit
=
edit
)
def
do_index
(
self
):
self
.
prologue
(
T_INDEX
)
files
=
self
.
dir
.
list
()
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
add
=
1
)
self
.
prologue
(
T_INDEX
)
files
=
self
.
dir
.
list
()
self
.
last_changed
(
files
)
self
.
format_index
(
files
,
add
=
1
)
def
format_index
(
self
,
files
,
add
=
0
,
localrefs
=
0
):
sec
=
0
for
file
in
files
:
try
:
entry
=
self
.
dir
.
open
(
file
)
except
NoSuchFile
:
continue
if
entry
.
sec
!=
sec
:
if
sec
:
if
add
:
emit
(
INDEX_ADDSECTION
,
sec
=
sec
)
emit
(
INDEX_ENDSECTION
,
sec
=
sec
)
sec
=
entry
.
sec
try
:
title
=
SECTION_TITLES
[
sec
]
except
KeyError
:
title
=
"Untitled"
emit
(
INDEX_SECTION
,
sec
=
sec
,
title
=
title
)
if
localrefs
:
emit
(
LOCAL_ENTRY
,
entry
)
else
:
emit
(
INDEX_ENTRY
,
entry
)
entry
.
emit_marks
()
if
sec
:
if
add
:
emit
(
INDEX_ADDSECTION
,
sec
=
sec
)
emit
(
INDEX_ENDSECTION
,
sec
=
sec
)
sec
=
0
for
file
in
files
:
try
:
entry
=
self
.
dir
.
open
(
file
)
except
NoSuchFile
:
continue
if
entry
.
sec
!=
sec
:
if
sec
:
if
add
:
emit
(
INDEX_ADDSECTION
,
sec
=
sec
)
emit
(
INDEX_ENDSECTION
,
sec
=
sec
)
sec
=
entry
.
sec
try
:
title
=
SECTION_TITLES
[
sec
]
except
KeyError
:
title
=
"Untitled"
emit
(
INDEX_SECTION
,
sec
=
sec
,
title
=
title
)
if
localrefs
:
emit
(
LOCAL_ENTRY
,
entry
)
else
:
emit
(
INDEX_ENTRY
,
entry
)
entry
.
emit_marks
()
if
sec
:
if
add
:
emit
(
INDEX_ADDSECTION
,
sec
=
sec
)
emit
(
INDEX_ENDSECTION
,
sec
=
sec
)
def
do_recent
(
self
):
if
not
self
.
ui
.
days
:
days
=
1
else
:
days
=
string
.
atof
(
self
.
ui
.
days
)
try
:
cutoff
=
now
-
days
*
24
*
3600
except
OverflowError
:
cutoff
=
0
list
=
[]
for
file
in
self
.
dir
.
list
():
entry
=
self
.
dir
.
open
(
file
)
if
not
entry
:
continue
mtime
=
entry
.
getmtime
()
if
mtime
>=
cutoff
:
list
.
append
((
mtime
,
file
))
list
.
sort
()
list
.
reverse
()
self
.
prologue
(
T_RECENT
)
if
days
<=
1
:
period
=
"
%.2
g hours"
%
(
days
*
24
)
else
:
period
=
"
%.6
g days"
%
days
if
not
list
:
emit
(
NO_RECENT
,
period
=
period
)
elif
len
(
list
)
==
1
:
emit
(
ONE_RECENT
,
period
=
period
)
else
:
emit
(
SOME_RECENT
,
period
=
period
,
count
=
len
(
list
))
self
.
format_all
(
map
(
lambda
(
mtime
,
file
):
file
,
list
),
headers
=
0
)
emit
(
TAIL_RECENT
)
if
not
self
.
ui
.
days
:
days
=
1
else
:
days
=
string
.
atof
(
self
.
ui
.
days
)
try
:
cutoff
=
now
-
days
*
24
*
3600
except
OverflowError
:
cutoff
=
0
list
=
[]
for
file
in
self
.
dir
.
list
():
entry
=
self
.
dir
.
open
(
file
)
if
not
entry
:
continue
mtime
=
entry
.
getmtime
()
if
mtime
>=
cutoff
:
list
.
append
((
mtime
,
file
))
list
.
sort
()
list
.
reverse
()
self
.
prologue
(
T_RECENT
)
if
days
<=
1
:
period
=
"
%.2
g hours"
%
(
days
*
24
)
else
:
period
=
"
%.6
g days"
%
days
if
not
list
:
emit
(
NO_RECENT
,
period
=
period
)
elif
len
(
list
)
==
1
:
emit
(
ONE_RECENT
,
period
=
period
)
else
:
emit
(
SOME_RECENT
,
period
=
period
,
count
=
len
(
list
))
self
.
format_all
(
map
(
lambda
(
mtime
,
file
):
file
,
list
),
headers
=
0
)
emit
(
TAIL_RECENT
)
def
do_roulette
(
self
):
import
whrandom
files
=
self
.
dir
.
list
()
if
not
files
:
self
.
error
(
"No entries."
)
return
file
=
whrandom
.
choice
(
files
)
self
.
prologue
(
T_ROULETTE
)
emit
(
ROULETTE
)
self
.
dir
.
show
(
file
)
import
whrandom
files
=
self
.
dir
.
list
()
if
not
files
:
self
.
error
(
"No entries."
)
return
file
=
whrandom
.
choice
(
files
)
self
.
prologue
(
T_ROULETTE
)
emit
(
ROULETTE
)
self
.
dir
.
show
(
file
)
def
do_help
(
self
):
self
.
prologue
(
T_HELP
)
emit
(
HELP
)
self
.
prologue
(
T_HELP
)
emit
(
HELP
)
def
do_show
(
self
):
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
self
.
prologue
(
T_SHOW
)
entry
.
show
()
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
self
.
prologue
(
T_SHOW
)
entry
.
show
()
def
do_add
(
self
):
self
.
prologue
(
T_ADD
)
emit
(
ADD_HEAD
)
sections
=
SECTION_TITLES
.
items
()
sections
.
sort
()
for
section
,
title
in
sections
:
emit
(
ADD_SECTION
,
section
=
section
,
title
=
title
)
emit
(
ADD_TAIL
)
self
.
prologue
(
T_ADD
)
emit
(
ADD_HEAD
)
sections
=
SECTION_TITLES
.
items
()
sections
.
sort
()
for
section
,
title
in
sections
:
emit
(
ADD_SECTION
,
section
=
section
,
title
=
title
)
emit
(
ADD_TAIL
)
def
do_delete
(
self
):
self
.
prologue
(
T_DELETE
)
emit
(
DELETE
)
self
.
prologue
(
T_DELETE
)
emit
(
DELETE
)
def
do_log
(
self
):
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
self
.
prologue
(
T_LOG
,
entry
)
emit
(
LOG
,
entry
)
self
.
rlog
(
interpolate
(
SH_RLOG
,
entry
),
entry
)
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
self
.
prologue
(
T_LOG
,
entry
)
emit
(
LOG
,
entry
)
self
.
rlog
(
interpolate
(
SH_RLOG
,
entry
),
entry
)
def
rlog
(
self
,
command
,
entry
=
None
):
output
=
os
.
popen
(
command
)
.
read
()
sys
.
stdout
.
write
(
'<PRE>'
)
athead
=
0
lines
=
string
.
split
(
output
,
'
\n
'
)
while
lines
and
not
lines
[
-
1
]:
del
lines
[
-
1
]
if
lines
:
line
=
lines
[
-
1
]
if
line
[:
1
]
==
'='
and
len
(
line
)
>=
40
and
\
line
==
line
[
0
]
*
len
(
line
):
del
lines
[
-
1
]
headrev
=
None
for
line
in
lines
:
if
entry
and
athead
and
line
[:
9
]
==
'revision '
:
rev
=
string
.
strip
(
line
[
9
:])
mami
=
revparse
(
rev
)
if
not
mami
:
print
line
else
:
emit
(
REVISIONLINK
,
entry
,
rev
=
rev
,
line
=
line
)
if
mami
[
1
]
>
1
:
prev
=
"
%
d.
%
d"
%
(
mami
[
0
],
mami
[
1
]
-
1
)
emit
(
DIFFLINK
,
entry
,
prev
=
prev
,
rev
=
rev
)
if
headrev
:
emit
(
DIFFLINK
,
entry
,
prev
=
rev
,
rev
=
headrev
)
else
:
headrev
=
rev
print
athead
=
0
else
:
athead
=
0
if
line
[:
1
]
==
'-'
and
len
(
line
)
>=
20
and
\
line
==
len
(
line
)
*
line
[
0
]:
athead
=
1
sys
.
stdout
.
write
(
'<HR>'
)
else
:
print
line
print
'</PRE>'
output
=
os
.
popen
(
command
)
.
read
()
sys
.
stdout
.
write
(
'<PRE>'
)
athead
=
0
lines
=
string
.
split
(
output
,
'
\n
'
)
while
lines
and
not
lines
[
-
1
]:
del
lines
[
-
1
]
if
lines
:
line
=
lines
[
-
1
]
if
line
[:
1
]
==
'='
and
len
(
line
)
>=
40
and
\
line
==
line
[
0
]
*
len
(
line
):
del
lines
[
-
1
]
headrev
=
None
for
line
in
lines
:
if
entry
and
athead
and
line
[:
9
]
==
'revision '
:
rev
=
string
.
strip
(
line
[
9
:])
mami
=
revparse
(
rev
)
if
not
mami
:
print
line
else
:
emit
(
REVISIONLINK
,
entry
,
rev
=
rev
,
line
=
line
)
if
mami
[
1
]
>
1
:
prev
=
"
%
d.
%
d"
%
(
mami
[
0
],
mami
[
1
]
-
1
)
emit
(
DIFFLINK
,
entry
,
prev
=
prev
,
rev
=
rev
)
if
headrev
:
emit
(
DIFFLINK
,
entry
,
prev
=
rev
,
rev
=
headrev
)
else
:
headrev
=
rev
print
athead
=
0
else
:
athead
=
0
if
line
[:
1
]
==
'-'
and
len
(
line
)
>=
20
and
\
line
==
len
(
line
)
*
line
[
0
]:
athead
=
1
sys
.
stdout
.
write
(
'<HR>'
)
else
:
print
line
print
'</PRE>'
def
do_revision
(
self
):
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
rev
=
self
.
ui
.
rev
mami
=
revparse
(
rev
)
if
not
mami
:
self
.
error
(
"Invalid revision number:
%
s."
%
`rev`
)
self
.
prologue
(
T_REVISION
,
entry
)
self
.
shell
(
interpolate
(
SH_REVISION
,
entry
,
rev
=
rev
))
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
rev
=
self
.
ui
.
rev
mami
=
revparse
(
rev
)
if
not
mami
:
self
.
error
(
"Invalid revision number:
%
s."
%
`rev`
)
self
.
prologue
(
T_REVISION
,
entry
)
self
.
shell
(
interpolate
(
SH_REVISION
,
entry
,
rev
=
rev
))
def
do_diff
(
self
):
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
prev
=
self
.
ui
.
prev
rev
=
self
.
ui
.
rev
mami
=
revparse
(
rev
)
if
not
mami
:
self
.
error
(
"Invalid revision number:
%
s."
%
`rev`
)
if
prev
:
if
not
revparse
(
prev
):
self
.
error
(
"Invalid previous revision number:
%
s."
%
`prev`
)
else
:
prev
=
'
%
d.
%
d'
%
(
mami
[
0
],
mami
[
1
])
self
.
prologue
(
T_DIFF
,
entry
)
self
.
shell
(
interpolate
(
SH_RDIFF
,
entry
,
rev
=
rev
,
prev
=
prev
))
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
prev
=
self
.
ui
.
prev
rev
=
self
.
ui
.
rev
mami
=
revparse
(
rev
)
if
not
mami
:
self
.
error
(
"Invalid revision number:
%
s."
%
`rev`
)
if
prev
:
if
not
revparse
(
prev
):
self
.
error
(
"Invalid previous revision number:
%
s."
%
`prev`
)
else
:
prev
=
'
%
d.
%
d'
%
(
mami
[
0
],
mami
[
1
])
self
.
prologue
(
T_DIFF
,
entry
)
self
.
shell
(
interpolate
(
SH_RDIFF
,
entry
,
rev
=
rev
,
prev
=
prev
))
def
shell
(
self
,
command
):
output
=
os
.
popen
(
command
)
.
read
()
sys
.
stdout
.
write
(
'<PRE>'
)
print
escape
(
output
)
print
'</PRE>'
output
=
os
.
popen
(
command
)
.
read
()
sys
.
stdout
.
write
(
'<PRE>'
)
print
escape
(
output
)
print
'</PRE>'
def
do_new
(
self
):
entry
=
self
.
dir
.
new
(
section
=
string
.
atoi
(
self
.
ui
.
section
))
entry
.
version
=
'*new*'
self
.
prologue
(
T_EDIT
)
emit
(
EDITHEAD
)
emit
(
EDITFORM1
,
entry
,
editversion
=
entry
.
version
)
emit
(
EDITFORM2
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
entry
.
show
(
edit
=
0
)
entry
=
self
.
dir
.
new
(
section
=
string
.
atoi
(
self
.
ui
.
section
))
entry
.
version
=
'*new*'
self
.
prologue
(
T_EDIT
)
emit
(
EDITHEAD
)
emit
(
EDITFORM1
,
entry
,
editversion
=
entry
.
version
)
emit
(
EDITFORM2
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
entry
.
show
(
edit
=
0
)
def
do_edit
(
self
):
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
entry
.
load_version
()
self
.
prologue
(
T_EDIT
)
emit
(
EDITHEAD
)
emit
(
EDITFORM1
,
entry
,
editversion
=
entry
.
version
)
emit
(
EDITFORM2
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
entry
.
show
(
edit
=
0
)
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
entry
.
load_version
()
self
.
prologue
(
T_EDIT
)
emit
(
EDITHEAD
)
emit
(
EDITFORM1
,
entry
,
editversion
=
entry
.
version
)
emit
(
EDITFORM2
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
entry
.
show
(
edit
=
0
)
def
do_review
(
self
):
send_my_cookie
(
self
.
ui
)
if
self
.
ui
.
editversion
==
'*new*'
:
sec
,
num
=
self
.
dir
.
parse
(
self
.
ui
.
file
)
entry
=
self
.
dir
.
new
(
section
=
sec
)
entry
.
version
=
"*new*"
if
entry
.
file
!=
self
.
ui
.
file
:
self
.
error
(
"Commit version conflict!"
)
emit
(
NEWCONFLICT
,
self
.
ui
,
sec
=
sec
,
num
=
num
)
return
else
:
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
entry
.
load_version
()
# Check that the FAQ entry number didn't change
if
string
.
split
(
self
.
ui
.
title
)[:
1
]
!=
string
.
split
(
entry
.
title
)[:
1
]:
self
.
error
(
"Don't change the entry number please!"
)
return
# Check that the edited version is the current version
if
entry
.
version
!=
self
.
ui
.
editversion
:
self
.
error
(
"Commit version conflict!"
)
emit
(
VERSIONCONFLICT
,
entry
,
self
.
ui
)
return
commit_ok
=
((
not
PASSWORD
or
self
.
ui
.
password
==
PASSWORD
)
and
self
.
ui
.
author
and
'@'
in
self
.
ui
.
email
and
self
.
ui
.
log
)
if
self
.
ui
.
commit
:
if
not
commit_ok
:
self
.
cantcommit
()
else
:
self
.
commit
(
entry
)
return
self
.
prologue
(
T_REVIEW
)
emit
(
REVIEWHEAD
)
entry
.
body
=
self
.
ui
.
body
entry
.
title
=
self
.
ui
.
title
entry
.
show
(
edit
=
0
)
emit
(
EDITFORM1
,
self
.
ui
,
entry
)
if
commit_ok
:
emit
(
COMMIT
)
else
:
emit
(
NOCOMMIT
)
emit
(
EDITFORM2
,
self
.
ui
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
send_my_cookie
(
self
.
ui
)
if
self
.
ui
.
editversion
==
'*new*'
:
sec
,
num
=
self
.
dir
.
parse
(
self
.
ui
.
file
)
entry
=
self
.
dir
.
new
(
section
=
sec
)
entry
.
version
=
"*new*"
if
entry
.
file
!=
self
.
ui
.
file
:
self
.
error
(
"Commit version conflict!"
)
emit
(
NEWCONFLICT
,
self
.
ui
,
sec
=
sec
,
num
=
num
)
return
else
:
entry
=
self
.
dir
.
open
(
self
.
ui
.
file
)
entry
.
load_version
()
# Check that the FAQ entry number didn't change
if
string
.
split
(
self
.
ui
.
title
)[:
1
]
!=
string
.
split
(
entry
.
title
)[:
1
]:
self
.
error
(
"Don't change the entry number please!"
)
return
# Check that the edited version is the current version
if
entry
.
version
!=
self
.
ui
.
editversion
:
self
.
error
(
"Commit version conflict!"
)
emit
(
VERSIONCONFLICT
,
entry
,
self
.
ui
)
return
commit_ok
=
((
not
PASSWORD
or
self
.
ui
.
password
==
PASSWORD
)
and
self
.
ui
.
author
and
'@'
in
self
.
ui
.
email
and
self
.
ui
.
log
)
if
self
.
ui
.
commit
:
if
not
commit_ok
:
self
.
cantcommit
()
else
:
self
.
commit
(
entry
)
return
self
.
prologue
(
T_REVIEW
)
emit
(
REVIEWHEAD
)
entry
.
body
=
self
.
ui
.
body
entry
.
title
=
self
.
ui
.
title
entry
.
show
(
edit
=
0
)
emit
(
EDITFORM1
,
self
.
ui
,
entry
)
if
commit_ok
:
emit
(
COMMIT
)
else
:
emit
(
NOCOMMIT
)
emit
(
EDITFORM2
,
self
.
ui
,
entry
,
load_my_cookie
())
emit
(
EDITFORM3
)
def
cantcommit
(
self
):
self
.
prologue
(
T_CANTCOMMIT
)
print
CANTCOMMIT_HEAD
if
not
self
.
ui
.
passwd
:
emit
(
NEED_PASSWD
)
if
not
self
.
ui
.
log
:
emit
(
NEED_LOG
)
if
not
self
.
ui
.
author
:
emit
(
NEED_AUTHOR
)
if
not
self
.
ui
.
email
:
emit
(
NEED_EMAIL
)
print
CANTCOMMIT_TAIL
self
.
prologue
(
T_CANTCOMMIT
)
print
CANTCOMMIT_HEAD
if
not
self
.
ui
.
passwd
:
emit
(
NEED_PASSWD
)
if
not
self
.
ui
.
log
:
emit
(
NEED_LOG
)
if
not
self
.
ui
.
author
:
emit
(
NEED_AUTHOR
)
if
not
self
.
ui
.
email
:
emit
(
NEED_EMAIL
)
print
CANTCOMMIT_TAIL
def
commit
(
self
,
entry
):
file
=
entry
.
file
# Normalize line endings in body
if
'
\r
'
in
self
.
ui
.
body
:
self
.
ui
.
body
=
re
.
sub
(
'
\r\n
?'
,
'
\n
'
,
self
.
ui
.
body
)
# Normalize whitespace in title
self
.
ui
.
title
=
string
.
join
(
string
.
split
(
self
.
ui
.
title
))
# Check that there were any changes
if
self
.
ui
.
body
==
entry
.
body
and
self
.
ui
.
title
==
entry
.
title
:
self
.
error
(
"You didn't make any changes!"
)
return
# XXX Should lock here
try
:
os
.
unlink
(
file
)
except
os
.
error
:
pass
try
:
f
=
open
(
file
,
'w'
)
except
IOError
,
why
:
self
.
error
(
CANTWRITE
,
file
=
file
,
why
=
why
)
return
date
=
time
.
ctime
(
now
)
emit
(
FILEHEADER
,
self
.
ui
,
os
.
environ
,
date
=
date
,
_file
=
f
,
_quote
=
0
)
f
.
write
(
'
\n
'
)
f
.
write
(
self
.
ui
.
body
)
f
.
write
(
'
\n
'
)
f
.
close
()
import
tempfile
tfn
=
tempfile
.
mktemp
()
f
=
open
(
tfn
,
'w'
)
emit
(
LOGHEADER
,
self
.
ui
,
os
.
environ
,
date
=
date
,
_file
=
f
)
f
.
close
()
command
=
interpolate
(
SH_LOCK
+
'
\n
'
+
SH_CHECKIN
,
file
=
file
,
tfn
=
tfn
)
p
=
os
.
popen
(
command
)
output
=
p
.
read
()
sts
=
p
.
close
()
# XXX Should unlock here
if
not
sts
:
self
.
prologue
(
T_COMMITTED
)
emit
(
COMMITTED
)
else
:
self
.
error
(
T_COMMITFAILED
)
emit
(
COMMITFAILED
,
sts
=
sts
)
print
'<PRE>
%
s</PRE>'
%
escape
(
output
)
try
:
os
.
unlink
(
tfn
)
except
os
.
error
:
pass
entry
=
self
.
dir
.
open
(
file
)
entry
.
show
()
file
=
entry
.
file
# Normalize line endings in body
if
'
\r
'
in
self
.
ui
.
body
:
self
.
ui
.
body
=
re
.
sub
(
'
\r\n
?'
,
'
\n
'
,
self
.
ui
.
body
)
# Normalize whitespace in title
self
.
ui
.
title
=
string
.
join
(
string
.
split
(
self
.
ui
.
title
))
# Check that there were any changes
if
self
.
ui
.
body
==
entry
.
body
and
self
.
ui
.
title
==
entry
.
title
:
self
.
error
(
"You didn't make any changes!"
)
return
# XXX Should lock here
try
:
os
.
unlink
(
file
)
except
os
.
error
:
pass
try
:
f
=
open
(
file
,
'w'
)
except
IOError
,
why
:
self
.
error
(
CANTWRITE
,
file
=
file
,
why
=
why
)
return
date
=
time
.
ctime
(
now
)
emit
(
FILEHEADER
,
self
.
ui
,
os
.
environ
,
date
=
date
,
_file
=
f
,
_quote
=
0
)
f
.
write
(
'
\n
'
)
f
.
write
(
self
.
ui
.
body
)
f
.
write
(
'
\n
'
)
f
.
close
()
import
tempfile
tfn
=
tempfile
.
mktemp
()
f
=
open
(
tfn
,
'w'
)
emit
(
LOGHEADER
,
self
.
ui
,
os
.
environ
,
date
=
date
,
_file
=
f
)
f
.
close
()
command
=
interpolate
(
SH_LOCK
+
'
\n
'
+
SH_CHECKIN
,
file
=
file
,
tfn
=
tfn
)
p
=
os
.
popen
(
command
)
output
=
p
.
read
()
sts
=
p
.
close
()
# XXX Should unlock here
if
not
sts
:
self
.
prologue
(
T_COMMITTED
)
emit
(
COMMITTED
)
else
:
self
.
error
(
T_COMMITFAILED
)
emit
(
COMMITFAILED
,
sts
=
sts
)
print
'<PRE>
%
s</PRE>'
%
escape
(
output
)
try
:
os
.
unlink
(
tfn
)
except
os
.
error
:
pass
entry
=
self
.
dir
.
open
(
file
)
entry
.
show
()
wiz
=
FaqWizard
()
wiz
.
go
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment