wikiupload 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/env python
  2. # wikiupload --- Put a wiki page on an Oddmuse wiki
  3. #
  4. # Copyright (C) 2004 Jorgen Schaefer <forcer@forcix.cx>
  5. # Copyright (C) 2005 Alex Schroeder <alex@emacswiki.org>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License
  9. # as published by the Free Software Foundation; either version 2
  10. # of the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. # 02111-1307, USA.
  21. # $Id: wikiupload,v 1.8 2010/02/08 13:40:59 as Exp $
  22. import mimetypes, httplib, urllib, re, urlparse, sys, getopt
  23. from time import time
  24. def main():
  25. summary="upload"
  26. username=""
  27. password=""
  28. type=""
  29. recent_edit="off"
  30. try:
  31. opts, args = getopt.getopt(sys.argv[1:],
  32. "ht:s:u:p:m:",
  33. ["help", "summary=", "user=", "password=", "type=", "minor-edit="])
  34. except getopt.GetoptError:
  35. usage(sys.stderr)
  36. sys.exit(1)
  37. if len(args) != 2:
  38. usage(sys.stderr)
  39. sys.exit(1)
  40. for opt, arg in opts:
  41. if opt in ("-h", "--help"):
  42. usage(sys.stdout)
  43. if opt in ("-s", "--summary"):
  44. summary = arg
  45. if opt in ("-u", "--user"):
  46. username = arg
  47. if opt in ("-p", "--password"):
  48. password = arg
  49. if opt in ("-t", "--type"):
  50. type = arg
  51. if opt in ("-m", "--minor-edit"):
  52. recent_edit="on"
  53. wikiput(args[1], args[0], summary=summary, username=username, password=password,
  54. type=type, recent_edit=recent_edit)
  55. def usage(out):
  56. """Display the usage information for this script.
  57. Options:
  58. out -- The file descriptor where to write the info.
  59. """
  60. out.write("Usage: wikiupload [OPTIONS] file wikipage\n"
  61. "Post the data in the file onto the wikipage described by wikipage.\n"
  62. "\n"
  63. "Example: wikiupload foaf.rdf http://your.domain.here/cgi-bin/wiki.pl/FOAF\n"
  64. "\n"
  65. "Options:\n"
  66. " -h --help Display this help\n"
  67. " -s --summary=S The summary line (default: upload)\n"
  68. " -u --user=U The username to use (default: none)\n"
  69. " -p --password=P The password to use (default: none)\n"
  70. " -t --type=T The MIME type to use (default: guessed)\n"
  71. " -m --minor-edit=B Whether this is a minor edit (default: no)\n")
  72. def wikiput(where, filename,
  73. summary="upload", username="", password="", type="", recent_edit="no"):
  74. (host, path, title) = parse_wiki_location(where)
  75. content = open(filename, "rb").read()
  76. files = [['file', filename, content]]
  77. params = [[ 'title', title ],
  78. [ 'summary', summary ],
  79. [ 'username', username ],
  80. [ 'pwd', password ],
  81. [ 'question', "1" ],
  82. [ 'recent_edit', recent_edit ]]
  83. (content_type, body) = encode_multipart_formdata(params, type, files);
  84. headers = {'Content-Type': content_type}
  85. conn = httplib.HTTPConnection(host)
  86. conn.request("POST", path, body, headers)
  87. response = conn.getresponse()
  88. data = response.read()
  89. conn.close()
  90. if response.status != 302:
  91. print "Uploading", filename, get_content_type(filename, type)
  92. print response.status, response.reason
  93. print response.read()
  94. if response.status == 415:
  95. print "Check your MIME types in one of these files:"
  96. print mimetypes.knownfiles
  97. sys.exit(1)
  98. def encode_multipart_formdata(fields, type, files):
  99. """
  100. fields is a sequence of (name, value) elements for regular form fields.
  101. files is a sequence of (name, filename, value) elements for data to be uploaded as files.
  102. Return (content_type, body) ready for httplib.HTTP instance
  103. """
  104. BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
  105. CRLF = '\r\n'
  106. L = []
  107. for (key, value) in fields:
  108. L.append('--' + BOUNDARY)
  109. L.append('Content-Disposition: form-data; name="%s"' % key)
  110. L.append('')
  111. L.append(value)
  112. for (key, filename, value) in files:
  113. L.append('--' + BOUNDARY)
  114. L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
  115. L.append('Content-Type: %s' % get_content_type(filename, type))
  116. L.append('')
  117. L.append(value)
  118. L.append('--' + BOUNDARY + '--')
  119. L.append('')
  120. body = CRLF.join(L)
  121. content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
  122. return content_type, body
  123. def get_content_type(filename, type):
  124. return type or mimetypes.guess_type(filename)[0] or 'application/octet-stream'
  125. def parse_wiki_location(where):
  126. """Return a tuple of host, path and page name for the wiki page
  127. WHERE.
  128. """
  129. (scheme, host, path, params, query, fragment) = urlparse.urlparse(where)
  130. if not query:
  131. list = path.split("/")
  132. query = list.pop()
  133. path = "/".join(list)
  134. return (host, path+params, query)
  135. if __name__ == "__main__":
  136. main()