Merge branch 'feature/docs' into develop

feature/documentation-builds-html
Isis Lovecruft 2013-04-11 18:40:32 +00:00
commit 7ae48bdfdf
No known key found for this signature in database
GPG Key ID: A3ADB67A2CDB8B35
4 changed files with 298 additions and 8 deletions

View File

@ -1,10 +1,11 @@
# python-gnupg #
================
Fork of python-gnupg-0.3.2, patched to remove Popen([...], shell=True).
Fork of python-gnupg-0.3.2, patched to remove ```Popen([...], shell=True)```.
### Installation ###
--------------------
#### From this git repository ####
To install this package from this git repository, do:
```
@ -19,15 +20,44 @@ Optionally to build the documentation after installation, do:
make docs
```
To get started using python-gnupg's API, see the documentation online at [XXX
FIXME add readthedocs link](), and import the module like so:
To get started using python-gnupg's API, see the [online documentation](https://python-gnupg.readthedocs.org/en/latest/),
and import the module like so:
```
>>> import gnupg
```
The primary interface class you'll likely want to interact with is
[```gnupg.GPG```](https://python-gnupg.readthedocs.org/en/latest/gnupg.html#gpg):
```
>>> gpg = gnupg.GPG(gpgbinary='/usr/bin/gpg',
... gpghome='./keys',
... pubring='pubring.gpg',
... secring='secring.gpg')
>>> batch_key_input = gpg.gen_key_input()
>>> print batch_key_input
Key-Type: RSA
Name-Email: isis@wintermute
Name-Comment: Generated by gnupg.py
Key-Length: 4096
Name-Real: Autogenerated Key
%pubring /home/isis/code/python-gnupg/keys/pubring.gpg
%secring /home/isis/code/python-gnupg/keys/secring.gpg
%commit
To install this package from a tarballed source distribution, do the following:
>>> key = gpg.gen_key(batch_key_input)
>>> print key.fingerprint
245D8FA30F543B742053949F553C0E154F2E7A98
1. Extract all the files in the distribution archive to some directory on your system.
2. In that directory, run "python setup.py install".
3. Optionally, run "python test_gnupg.py" to ensure that the package is working as expected.
```
#### From PyPI ####
Hold your horses, boy. I haven't finished development, so the packages on
[PyPI](https://pypi.python.org) are still the old versions belonging to the
other authors.
### Bug Reports & Feature Requests ###
Our bugtracker is [here](https://leap.se/code/projects/eip_server/issue/new).
Please use that for bug reports and feature requests instead of github's
tracker. We're using github for code commenting and review between
collaborators.

Binary file not shown.

Binary file not shown.

260
report-a-bug 100644
View File

@ -0,0 +1,260 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
'''
report-a-bug
------------
File a bug against python-gnupg.
:authors: Wade Leftwich,
Will Holcomb, <wholcomb@gmail.com>
Isis Lovecruft, <isis@leap.se>
:license: AGPLv3, see LICENSE and COPYRIGHT files
:copyright: © 2002-2013 Wade Leftwich
© 2006 Will Holcomb
© 2013 Isis Agora Lovecruft
:date: 11 April 2013
:version: 0.0.1
'''
from __future__ import print_function
from cStringIO import StringIO
from datetime import datetime
import cookielib
import mimetools
import mimetypes
#import httplib
import os
import stat
import tempfile
import urllib
import urllib2
# Controls how sequences are uncoded. If true, elements may be given multiple
# values by assigning a sequence.
doseq = 1
def _has_py3k():
"""Check if we're running on Python>=3.0."""
try:
unicode
return False
except NameError:
return True
## patch the stupid Python2.x input() problem:
if not _has_py3k():
input = raw_input
def _today():
"""Get the current date as a string in the form %Y-%m-%d."""
now_string = datetime.now().__str__()
return now_string.split(' ', 1)[0]
def _create_upload_list():
"""Create a dictionary containing information about files to upload."""
upload_list = list()
WANT_UPLOAD = True
FILE_NUMBER = 1
FILENAME_FIELD = 'attachments[' + str(FILE_NUMBER) + '][file]'
FILEDESC_FIELD = 'attachments[' + str(FILE_NUMBER) + '][description]'
while WANT_UPLOAD:
do_upload = input("Would you like to attach a file to this ticket? "
+ "(y/N) ")
if do_upload.strip() == "":
WANT_UPLOAD = False
break
else:
WANT_UPLOAD = True
upload = input("Please specify the file to upload, as a filesystem "
+ "absolute path or as relative to this directory (%s): "
% os.getcwd()).strip()
if len(upload) > 0:
if upload.startswith('~'):
upload = os.path.expanduser(upload)
if not os.path.isabs(upload):
upload = os.path.abspath(upload)
try:
assert os.path.isfile(upload), "is not a file"
except AssertionError as ae:
print("Skipping: '%s' %s" % (upload, ae.message))
else:
upload_fields = {'fields': [FILENAME_FIELD, FILEDESC_FIELD],
'filepath': upload,}
upload_list.append(upload_fields)
FILE_NUMBER += 1
return upload_list
def _create_fields_and_headers(host, url, assign_to=None,
category=None, target_version=None):
REPO_NAME = os.getcwd().rsplit(os.path.sep, 1)[1]
subject = input("Please provide a brief subject line for the ticket: ")
subject = REPO_NAME + ": " + subject
descript = input("Ticket description:\n ")
whatisit = input("Is this a feature request or a bug report? "
+ "(1=feature, 2=bug) ")
if whatisit not in ['1', '2']:
whatisit = '2'
serious = input("How important is this? (1=important, 2=normal, 3=trivial) ")
if serious not in ['1', '2', '3']:
serious = '2'
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-us,en-gb;q=0.9,en;',
'Connection': 'keep-alive',
'DNT': '1',
'Host': host,
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0', }
fields = {
'issue[tracker_id]': whatisit,
'issue[subject]': subject,
'issue[description]': descript,
'issue[status_id]': '2',
'issue[priority_id]': serious,
'issue[assigned_to_id]': assign_to,
'issue[category_id]': category,
'issue[fixed_version_id]': target_version,
'issue[start_date]': _today(),
'issue[due_date]': '',
'issue[estimated_hours]': '',
'issue[done_ratio]': '0',
'issue[custom_field_values][3]': '',
'issue[custom_field_values][4]': '',
'issue[custom_field_values][5]': '0',
'send_notification': '0',
'send_notification': '1',
'commit': 'Create', }
return fields, headers
class Callable:
def __init__(self, anycallable):
self.__call__ = anycallable
class MultipartPostHandler(urllib2.BaseHandler):
handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first
def http_request(self, request):
data = request.get_data()
if data is not None and type(data) != str:
v_files = []
v_vars = []
try:
for (key, value) in data.items():
if type(value) == file:
v_files.append((key, value))
else:
v_vars.append((key, value))
except TypeError:
systype, value, traceback = sys.exc_info()
raise TypeError("not non-string sequence or mapping object\n%s"
% traceback)
if len(v_files) == 0:
data = urllib.urlencode(v_vars, doseq)
else:
boundary, data = self.multipart_encode(v_vars, v_files)
contenttype = 'multipart/form-data; boundary=%s' % boundary
if (request.has_header('Content-Type') and request.get_header(
'Content-Type').find('multipart/form-data') != 0):
print("Replacing %s with %s"
% (request.get_header('content-type'),
'multipart/form-data'))
request.add_unredirected_header('Content-Type', contenttype)
request.add_data(data)
return request
def multipart_encode(self, fields=None, upload_list=None,
boundary=None, buf=None):
if fields is None:
fields = self.fields
if upload_list is None:
upload_list = self.upload_list
if boundary is None:
boundary = mimetools.choose_boundary()
if buf is None:
buf = StringIO()
for (key, value) in fields:
buf.write('--%s\r\n' % boundary)
buf.write('Content-Disposition: form-data; name="%s"' % key)
buf.write('\r\n\r\n' + value + '\r\n')
if isinstance(upload_list, list) and len(upload_list) > 0:
for upload in upload_list:
for (name, filepath) in upload:
with open(filepath) as fd:
file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
filename = fd.name.split('/')[-1]
contenttype = mimetypes.guess_type(filename)[0] \
or 'application/octet-stream'
buf.write('--%s\r\n' % boundary)
buf.write('Content-Disposition: form-data; ')
buf.write('name="%s"; filename="%s"'
% (name[0], filename))
buf.write('Content-Type: %s\r\n' % contenttype)
# buf.write('Content-Length: %s\r\n' % file_size)
fd.seek(0)
buf.write('\r\n' + fd.read() + '\r\n')
buf.write('--' + boundary + '--\r\n\r\n')
buf.write('--%s\r\n' % boundary)
buf.write('Content-Disposition: form-data; ')
buf.write('name="%s"; filename="%s"'
% (name[1], filename))
buf.write('\r\n\r\n')
buf.write('--' + boundary + '--\r\n\r\n')
buf = buf.getvalue()
return boundary, buf
multipart_encode = Callable(multipart_encode)
https_request = http_request
if __name__ == "__main__":
raise SystemExit("Please fix me! This script needs a login handler.\n"
+ "Everything else is finished.")
## if you're reusing this script please change these!
host = 'leap.se'
selector = '/code/projects/eip-server/issues/new'
assign_to = '30' ## isis
category = '26' ## email
target_version = '29' ## the close future
url = 'https://' + host + selector
fields, headers = _create_fields_and_headers(host, selector, assign_to,
category, target_version)
upload_list = _create_upload_list()
cookies = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
MultipartPostHandler())
urllib2.install_opener(opener)
temp = tempfile.mkstemp(suffix=".html")
temp1 = tempfile.mkstemp(suffix=".html")
os.write(temp[0], opener.open('https://'+host+'/code/login',
{'username': 'cypherpunks',
'password': 'writecode'}).read())
for index,upload in enumerate(upload_list):
for (field, filepath) in upload:
fields['file'+'-'+index] = open(filepath, 'rb')
res = opener.open(url, fields)
print("Posted to: %s" % res.geturl())
print("Server response: %s " % res.code)
print(res.info())
print(res.read())
os.remove(temp[1])