mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-08 21:53:36 +00:00
huge dump for Classroom, CloudPrint and batch fixes/improvements
This commit is contained in:
@ -10,6 +10,7 @@ xcopy LICENSE gam\
|
|||||||
xcopy whatsnew.txt gam\
|
xcopy whatsnew.txt gam\
|
||||||
xcopy cacert.pem gam\
|
xcopy cacert.pem gam\
|
||||||
xcopy admin-settings-v1.json gam\
|
xcopy admin-settings-v1.json gam\
|
||||||
|
xcopy cloudprint-v2.json gam\
|
||||||
del gam\w9xpopen.exe
|
del gam\w9xpopen.exe
|
||||||
"%ProgramFiles(x86)%\7-Zip\7z.exe" a -tzip gam-%1-windows.zip gam\ -xr!.svn
|
"%ProgramFiles(x86)%\7-Zip\7z.exe" a -tzip gam-%1-windows.zip gam\ -xr!.svn
|
||||||
|
|
||||||
@ -18,4 +19,5 @@ xcopy LICENSE gam-64\
|
|||||||
xcopy whatsnew.txt gam-64\
|
xcopy whatsnew.txt gam-64\
|
||||||
xcopy cacert.pem gam-64\
|
xcopy cacert.pem gam-64\
|
||||||
xcopy admin-settings-v1.json gam-64\
|
xcopy admin-settings-v1.json gam-64\
|
||||||
|
xcopy cloudprint-v2.json gam-64\
|
||||||
"%ProgramFiles(x86)%\7-Zip\7z.exe" a -tzip gam-%1-windows-x64.zip gam-64\ -xr!.svn
|
"%ProgramFiles(x86)%\7-Zip\7z.exe" a -tzip gam-%1-windows-x64.zip gam-64\ -xr!.svn
|
||||||
|
486
cloudprint-v2.json
Normal file
486
cloudprint-v2.json
Normal file
@ -0,0 +1,486 @@
|
|||||||
|
{
|
||||||
|
"kind": "discovery#restDescription",
|
||||||
|
"discoveryVersion": "v1",
|
||||||
|
"id": "cloudprint:v2",
|
||||||
|
"name": "cloudprint",
|
||||||
|
"version": "v2",
|
||||||
|
"revision": "20150605",
|
||||||
|
"title": "Cloud Print API",
|
||||||
|
"description": "Lets you access Cloud Print Printers",
|
||||||
|
"ownerDomain": "google.com",
|
||||||
|
"ownerName": "Google",
|
||||||
|
"icons": {
|
||||||
|
"x16": "http://www.google.com/images/icons/product/search-16.gif",
|
||||||
|
"x32": "http://www.google.com/images/icons/product/search-32.gif"
|
||||||
|
},
|
||||||
|
"documentationLink": "https://developers.google.com/cloud-print",
|
||||||
|
"protocol": "rest",
|
||||||
|
"baseUrl": "https://www.google.com/",
|
||||||
|
"basePath": "/cloudprint/",
|
||||||
|
"rootUrl": "https://www.google.com/",
|
||||||
|
"servicePath": "/cloudprint/",
|
||||||
|
"parameters": {
|
||||||
|
"prettyPrint": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Returns response with indentations and line breaks.",
|
||||||
|
"default": "true",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"oauth2": {
|
||||||
|
"scopes": {
|
||||||
|
"https://www.googleapis.com/auth/cloudprint": {
|
||||||
|
"description": "Manage Cloud Print"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemas": {
|
||||||
|
"Job": {
|
||||||
|
"id": "Job",
|
||||||
|
"type": "object",
|
||||||
|
"description": "Job Object",
|
||||||
|
"properties": {
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Job Title"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique ID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Jobs": {
|
||||||
|
"id": "Jobs",
|
||||||
|
"type": "object",
|
||||||
|
"description": "List of Jobs.",
|
||||||
|
"properties": {
|
||||||
|
"jobs": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of job objects.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "Job"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Printer": {
|
||||||
|
"id": "Printer",
|
||||||
|
"type": "object",
|
||||||
|
"description": "Printer Object",
|
||||||
|
"properties": {
|
||||||
|
"displayName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Display Name"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique ID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Printers": {
|
||||||
|
"id": "Printers",
|
||||||
|
"type": "object",
|
||||||
|
"description": "List of Printers.",
|
||||||
|
"properties": {
|
||||||
|
"printers": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of printer objects.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "Printer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"jobs": {
|
||||||
|
"methods": {
|
||||||
|
"delete": {
|
||||||
|
"id": "cloudprint.jobs.delete",
|
||||||
|
"path": "deletejob",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"jobid": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query",
|
||||||
|
"required": "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fetch": {
|
||||||
|
"id": "cloudprint.jobs.fetch",
|
||||||
|
"path": "fetch",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Jobs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"getticket": {
|
||||||
|
"id": "cloudprint.jobs.getticket",
|
||||||
|
"path": "ticket",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"jobid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"use_cjt": {
|
||||||
|
"type": "boolean",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"id": "cloudprint.jobs.list",
|
||||||
|
"path": "jobs",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"offset": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"sortorder": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Jobs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"update": {
|
||||||
|
"id": "cloudprint.jobs.update",
|
||||||
|
"path": "control",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"jobid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"semantic_state_diff": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Jobs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resubmit": {
|
||||||
|
"id": "cloudprint.jobs.resubmit",
|
||||||
|
"path": "resubmit",
|
||||||
|
"httpMethod": "POST",
|
||||||
|
"description": "resubmit a job to new printer.",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"jobid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"ticket": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Job"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"submit": {
|
||||||
|
"id": "cloudprint.jobs.submit",
|
||||||
|
"path": "submit",
|
||||||
|
"httpMethod": "POST",
|
||||||
|
"description": "Send a print job to cloud print.",
|
||||||
|
"request": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"ticket": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"contentType": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"tag": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Job"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"printers": {
|
||||||
|
"methods": {
|
||||||
|
"get": {
|
||||||
|
"id": "cloudprint.printers.get",
|
||||||
|
"path": "printer",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"extra_fields": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Printer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"id": "cloudprint.printers.list",
|
||||||
|
"path": "search",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"description": "List all printers",
|
||||||
|
"parameters": {
|
||||||
|
"q": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Query list of printers",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "limit results to printers of type",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"connection_status": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "limit results to printers with this status",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"extra_fields": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "include extra fields",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"$ref": "Printers"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"share": {
|
||||||
|
"id": "cloudprint.printers.share",
|
||||||
|
"path": "share",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"description": "Share printer with user, group or domain",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"skip_notification": {
|
||||||
|
"type": "boolean",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"public": {
|
||||||
|
"type": "boolean",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unshare": {
|
||||||
|
"id": "cloudprint.printers.unshare",
|
||||||
|
"path": "unshare",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"description": "unshare printer with user, group or domain",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"public": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"id": "cloudprint.printers.delete",
|
||||||
|
"path": "delete",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"description": "delete a printer",
|
||||||
|
"parameters": {
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"update": {
|
||||||
|
"id": "cloudprint.printers.update",
|
||||||
|
"path": "update",
|
||||||
|
"httpMethod": "GET",
|
||||||
|
"description": "update a printer",
|
||||||
|
"parameters": {
|
||||||
|
"isTosAccepted": {
|
||||||
|
"type": "boolean",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"gcpVersion": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"setupUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"supportUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"firmware": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"currentQuota": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"public": {
|
||||||
|
"type": "boolean",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"manufacturer": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"defaultDisplayName": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"displayName": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"updateUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"ownerId": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"printerid": {
|
||||||
|
"type": "string",
|
||||||
|
"required": "true",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"quotaEnabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"location": "query"
|
||||||
|
},
|
||||||
|
"dailyQuota": {
|
||||||
|
"type": "string",
|
||||||
|
"location": "query"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,4 +12,4 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
__version__ = "1.4.0"
|
__version__ = "1.4.1"
|
||||||
|
@ -56,6 +56,7 @@ from googleapiclient.errors import MediaUploadSizeError
|
|||||||
from googleapiclient.errors import UnacceptableMimeTypeError
|
from googleapiclient.errors import UnacceptableMimeTypeError
|
||||||
from googleapiclient.errors import UnknownApiNameOrVersion
|
from googleapiclient.errors import UnknownApiNameOrVersion
|
||||||
from googleapiclient.errors import UnknownFileType
|
from googleapiclient.errors import UnknownFileType
|
||||||
|
from googleapiclient.http import BatchHttpRequest
|
||||||
from googleapiclient.http import HttpRequest
|
from googleapiclient.http import HttpRequest
|
||||||
from googleapiclient.http import MediaFileUpload
|
from googleapiclient.http import MediaFileUpload
|
||||||
from googleapiclient.http import MediaUpload
|
from googleapiclient.http import MediaUpload
|
||||||
@ -950,6 +951,27 @@ class Resource(object):
|
|||||||
self._add_next_methods(self._resourceDesc, self._schema)
|
self._add_next_methods(self._resourceDesc, self._schema)
|
||||||
|
|
||||||
def _add_basic_methods(self, resourceDesc, rootDesc, schema):
|
def _add_basic_methods(self, resourceDesc, rootDesc, schema):
|
||||||
|
# If this is the root Resource, add a new_batch_http_request() method.
|
||||||
|
if resourceDesc == rootDesc:
|
||||||
|
batch_uri = '%s%s' % (
|
||||||
|
rootDesc['rootUrl'], rootDesc.get('batchPath', 'batch'))
|
||||||
|
def new_batch_http_request(callback=None):
|
||||||
|
"""Create a BatchHttpRequest object based on the discovery document.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback: callable, A callback to be called for each response, of the
|
||||||
|
form callback(id, response, exception). The first parameter is the
|
||||||
|
request id, and the second is the deserialized response object. The
|
||||||
|
third is an apiclient.errors.HttpError exception object if an HTTP
|
||||||
|
error occurred while processing the request, or None if no error
|
||||||
|
occurred.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A BatchHttpRequest object based on the discovery document.
|
||||||
|
"""
|
||||||
|
return BatchHttpRequest(callback=callback, batch_uri=batch_uri)
|
||||||
|
self._set_dynamic_attr('new_batch_http_request', new_batch_http_request)
|
||||||
|
|
||||||
# Add basic methods to Resource
|
# Add basic methods to Resource
|
||||||
if 'methods' in resourceDesc:
|
if 'methods' in resourceDesc:
|
||||||
for methodName, methodDesc in six.iteritems(resourceDesc['methods']):
|
for methodName, methodDesc in six.iteritems(resourceDesc['methods']):
|
||||||
|
@ -37,6 +37,8 @@ class HttpError(Error):
|
|||||||
@util.positional(3)
|
@util.positional(3)
|
||||||
def __init__(self, resp, content, uri=None):
|
def __init__(self, resp, content, uri=None):
|
||||||
self.resp = resp
|
self.resp = resp
|
||||||
|
if not isinstance(content, bytes):
|
||||||
|
raise TypeError("HTTP content should be bytes")
|
||||||
self.content = content
|
self.content = content
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
|
|
||||||
@ -44,7 +46,7 @@ class HttpError(Error):
|
|||||||
"""Calculate the reason for the error from the response content."""
|
"""Calculate the reason for the error from the response content."""
|
||||||
reason = self.resp.reason
|
reason = self.resp.reason
|
||||||
try:
|
try:
|
||||||
data = json.loads(self.content)
|
data = json.loads(self.content.decode('utf-8'))
|
||||||
reason = data['error']['message']
|
reason = data['error']['message']
|
||||||
except (ValueError, KeyError):
|
except (ValueError, KeyError):
|
||||||
pass
|
pass
|
||||||
|
@ -1120,10 +1120,6 @@ class BatchHttpRequest(object):
|
|||||||
g.flatten(msg, unixfrom=False)
|
g.flatten(msg, unixfrom=False)
|
||||||
body = fp.getvalue()
|
body = fp.getvalue()
|
||||||
|
|
||||||
# Strip off the \n\n that the MIME lib tacks onto the end of the payload.
|
|
||||||
if request.body is None:
|
|
||||||
body = body[:-2]
|
|
||||||
|
|
||||||
return status_line + body
|
return status_line + body
|
||||||
|
|
||||||
def _deserialize_response(self, payload):
|
def _deserialize_response(self, payload):
|
||||||
@ -1252,11 +1248,12 @@ class BatchHttpRequest(object):
|
|||||||
if resp.status >= 300:
|
if resp.status >= 300:
|
||||||
raise HttpError(resp, content, uri=self._batch_uri)
|
raise HttpError(resp, content, uri=self._batch_uri)
|
||||||
|
|
||||||
# Now break out the individual responses and store each one.
|
|
||||||
boundary, _ = content.split(None, 1)
|
|
||||||
|
|
||||||
# Prepend with a content-type header so FeedParser can handle it.
|
# Prepend with a content-type header so FeedParser can handle it.
|
||||||
header = 'content-type: %s\r\n\r\n' % resp['content-type']
|
header = 'content-type: %s\r\n\r\n' % resp['content-type']
|
||||||
|
# PY3's FeedParser only accepts unicode. So we should decode content
|
||||||
|
# here, and encode each payload again.
|
||||||
|
if six.PY3:
|
||||||
|
content = content.decode('utf-8')
|
||||||
for_parser = header + content
|
for_parser = header + content
|
||||||
|
|
||||||
parser = FeedParser()
|
parser = FeedParser()
|
||||||
@ -1270,6 +1267,9 @@ class BatchHttpRequest(object):
|
|||||||
for part in mime_response.get_payload():
|
for part in mime_response.get_payload():
|
||||||
request_id = self._header_to_id(part['Content-ID'])
|
request_id = self._header_to_id(part['Content-ID'])
|
||||||
response, content = self._deserialize_response(part.get_payload())
|
response, content = self._deserialize_response(part.get_payload())
|
||||||
|
# We encode content here to emulate normal http response.
|
||||||
|
if isinstance(content, six.text_type):
|
||||||
|
content = content.encode('utf-8')
|
||||||
self._responses[request_id] = (response, content)
|
self._responses[request_id] = (response, content)
|
||||||
|
|
||||||
@util.positional(1)
|
@util.positional(1)
|
||||||
@ -1458,7 +1458,7 @@ class HttpMock(object):
|
|||||||
headers: dict, header to return with response
|
headers: dict, header to return with response
|
||||||
"""
|
"""
|
||||||
if headers is None:
|
if headers is None:
|
||||||
headers = {'status': '200 OK'}
|
headers = {'status': '200'}
|
||||||
if filename:
|
if filename:
|
||||||
f = open(filename, 'r')
|
f = open(filename, 'r')
|
||||||
self.data = f.read()
|
self.data = f.read()
|
||||||
@ -1536,6 +1536,8 @@ class HttpMockSequence(object):
|
|||||||
content = body
|
content = body
|
||||||
elif content == 'echo_request_uri':
|
elif content == 'echo_request_uri':
|
||||||
content = uri
|
content = uri
|
||||||
|
if isinstance(content, six.text_type):
|
||||||
|
content = content.encode('utf-8')
|
||||||
return httplib2.Response(resp), content
|
return httplib2.Response(resp), content
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ __contributors__ = ["Thomas Broyer (t.broyer@ltgt.net)",
|
|||||||
"Sam Ruby",
|
"Sam Ruby",
|
||||||
"Louis Nyffenegger"]
|
"Louis Nyffenegger"]
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__version__ = "0.9"
|
__version__ = "0.9.1"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@ -255,8 +255,8 @@ def safename(filename):
|
|||||||
filename = re_slash.sub(",", filename)
|
filename = re_slash.sub(",", filename)
|
||||||
|
|
||||||
# limit length of filename
|
# limit length of filename
|
||||||
if len(filename)>64:
|
if len(filename)>200:
|
||||||
filename=filename[:64]
|
filename=filename[:200]
|
||||||
return ",".join((filename, filemd5))
|
return ",".join((filename, filemd5))
|
||||||
|
|
||||||
NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
|
NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
|
||||||
@ -749,12 +749,27 @@ class ProxyInfo(object):
|
|||||||
bypass_hosts = ()
|
bypass_hosts = ()
|
||||||
|
|
||||||
def __init__(self, proxy_type, proxy_host, proxy_port,
|
def __init__(self, proxy_type, proxy_host, proxy_port,
|
||||||
proxy_rdns=None, proxy_user=None, proxy_pass=None):
|
proxy_rdns=True, proxy_user=None, proxy_pass=None):
|
||||||
"""The parameter proxy_type must be set to one of socks.PROXY_TYPE_XXX
|
"""
|
||||||
constants. For example:
|
Args:
|
||||||
|
proxy_type: The type of proxy server. This must be set to one of
|
||||||
|
socks.PROXY_TYPE_XXX constants. For example:
|
||||||
|
|
||||||
p = ProxyInfo(proxy_type=socks.PROXY_TYPE_HTTP,
|
p = ProxyInfo(proxy_type=socks.PROXY_TYPE_HTTP,
|
||||||
proxy_host='localhost', proxy_port=8000)
|
proxy_host='localhost', proxy_port=8000)
|
||||||
|
|
||||||
|
proxy_host: The hostname or IP address of the proxy server.
|
||||||
|
|
||||||
|
proxy_port: The port that the proxy server is running on.
|
||||||
|
|
||||||
|
proxy_rdns: If True (default), DNS queries will not be performed
|
||||||
|
locally, and instead, handed to the proxy to resolve. This is useful
|
||||||
|
if the network does not allow resolution of non-local names. In
|
||||||
|
httplib2 0.9 and earlier, this defaulted to False.
|
||||||
|
|
||||||
|
proxy_user: The username used to authenticate with the proxy server.
|
||||||
|
|
||||||
|
proxy_pass: The password used to authenticate with the proxy server.
|
||||||
"""
|
"""
|
||||||
self.proxy_type = proxy_type
|
self.proxy_type = proxy_type
|
||||||
self.proxy_host = proxy_host
|
self.proxy_host = proxy_host
|
||||||
@ -871,12 +886,12 @@ class HTTPConnectionWithTimeout(httplib.HTTPConnection):
|
|||||||
if self.proxy_info and self.proxy_info.isgood():
|
if self.proxy_info and self.proxy_info.isgood():
|
||||||
use_proxy = True
|
use_proxy = True
|
||||||
proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass = self.proxy_info.astuple()
|
proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass = self.proxy_info.astuple()
|
||||||
else:
|
|
||||||
use_proxy = False
|
|
||||||
if use_proxy and proxy_rdns:
|
|
||||||
host = proxy_host
|
host = proxy_host
|
||||||
port = proxy_port
|
port = proxy_port
|
||||||
else:
|
else:
|
||||||
|
use_proxy = False
|
||||||
|
|
||||||
host = self.host
|
host = self.host
|
||||||
port = self.port
|
port = self.port
|
||||||
|
|
||||||
@ -993,12 +1008,12 @@ class HTTPSConnectionWithTimeout(httplib.HTTPSConnection):
|
|||||||
if self.proxy_info and self.proxy_info.isgood():
|
if self.proxy_info and self.proxy_info.isgood():
|
||||||
use_proxy = True
|
use_proxy = True
|
||||||
proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass = self.proxy_info.astuple()
|
proxy_type, proxy_host, proxy_port, proxy_rdns, proxy_user, proxy_pass = self.proxy_info.astuple()
|
||||||
else:
|
|
||||||
use_proxy = False
|
|
||||||
if use_proxy and proxy_rdns:
|
|
||||||
host = proxy_host
|
host = proxy_host
|
||||||
port = proxy_port
|
port = proxy_port
|
||||||
else:
|
else:
|
||||||
|
use_proxy = False
|
||||||
|
|
||||||
host = self.host
|
host = self.host
|
||||||
port = self.port
|
port = self.port
|
||||||
|
|
||||||
@ -1481,7 +1496,7 @@ class Http(object):
|
|||||||
info = email.Message.Message()
|
info = email.Message.Message()
|
||||||
cached_value = None
|
cached_value = None
|
||||||
if self.cache:
|
if self.cache:
|
||||||
cachekey = defrag_uri
|
cachekey = defrag_uri.encode('utf-8')
|
||||||
cached_value = self.cache.get(cachekey)
|
cached_value = self.cache.get(cachekey)
|
||||||
if cached_value:
|
if cached_value:
|
||||||
# info = email.message_from_string(cached_value)
|
# info = email.message_from_string(cached_value)
|
||||||
|
11
whatsnew.txt
11
whatsnew.txt
@ -1,3 +1,14 @@
|
|||||||
|
GAM 3.5
|
||||||
|
-Support for the new Google Classroom API.
|
||||||
|
-create, update, info and delete courses
|
||||||
|
-add, remove and sync course teachers and students
|
||||||
|
-print courses and course participants
|
||||||
|
-Google CloudPrint API Support
|
||||||
|
-update, info, delete and report printers
|
||||||
|
-share, unshare and get ACLs for printers
|
||||||
|
-submit, cancel, report and delete print jobs
|
||||||
|
-Bug fixes and improvements to GAM batch commands
|
||||||
|
|
||||||
GAM 3.45
|
GAM 3.45
|
||||||
-add six.py to solve compatability issues on OS X and Linux
|
-add six.py to solve compatability issues on OS X and Linux
|
||||||
-be conservative with password hashing to prevent timeouts
|
-be conservative with password hashing to prevent timeouts
|
||||||
|
Reference in New Issue
Block a user