def wrapper(http_request, factory_name, *args, **kwargs): """ Get factory by name and log errors in the database. """ from shotserver04.factories.models import Factory # Shortcut for nested calls, e.g. nonces.verify if isinstance(factory_name, Factory): factory = factory_name return func(http_request, factory, *args, **kwargs) # Get factory by name and run wrapped function factory = get_or_fault(Factory, name=factory_name) try: return func(http_request, factory, *args, **kwargs) except xmlrpclib.Fault, fault: fault_class = fault.faultCode / 100 if fault_class not in (2, 5): # Success or server error from shotserver04.messages.models import FactoryError # Save error message in the database FactoryError.objects.create(factory=factory, code=fault.faultCode, message=fault.faultString, request=getattr(fault, 'request', None), hashkey=getattr(fault, 'hashkey', None)) browser = getattr(fault, 'browser', None) if browser is not None: browser.update_fields(last_error=datetime.now()) raise
def wrapper(http_request, factory_name, *args, **kwargs): """ Get factory by name and log errors in the database. """ from shotserver04.factories.models import Factory # Shortcut for nested calls, e.g. nonces.verify if isinstance(factory_name, Factory): factory = factory_name return func(http_request, factory, *args, **kwargs) # Get factory by name and run wrapped function factory = get_or_fault(Factory, name=factory_name) try: return func(http_request, factory, *args, **kwargs) except xmlrpclib.Fault, fault: fault_class = fault.faultCode / 100 if fault_class not in (2, 5): # Success or server error from shotserver04.messages.models import FactoryError # Save error message in the database FactoryError.objects.create( factory=factory, code=fault.faultCode, message=fault.faultString, request=getattr(fault, 'request', None), hashkey=getattr(fault, 'hashkey', None)) browser = getattr(fault, 'browser', None) if browser is not None: browser.update_fields(last_error=datetime.now()) raise
def close_request(request_id, factory, screenshot): """ Close a screenshot request after it has been completed. """ # Check again that no other factory has locked the request request = get_or_fault(Request, pk=request_id) try: request.check_factory_lock(factory) except Fault: screenshot.delete() raise # Close the request request.update_fields(screenshot=screenshot)
def upload(http_request, factory, encrypted_password, request, screenshot): """ Submit a multi-page screenshot as a lossless PNG file. Arguments ~~~~~~~~~ * factory_name string (lowercase, normally from hostname) * encrypted_password string (lowercase hexadecimal, length 32) * request int (from requests.poll) * screenshot binary (BASE64-encoded PNG file) See nonces.verify for how to encrypt your password. Return value ~~~~~~~~~~~~ * hashkey string (lowercase hexadecimal, length 32) Users can see the resulting uploaded screenshot at http://browsershots.org/screenshots/hashkey/ """ # Verify authentication nonces.verify(http_request, factory, encrypted_password) request_id = request request = get_or_fault(Request, pk=request_id) request_group = request.request_group # Make sure the request was locked by this factory request.check_factory_lock(factory) # Store and check screenshot file hashkey = storage.save_upload(screenshot) bytes = storage.png_filesize(hashkey) # Make sure the request was redirected by the browser browser = request.browser if browser is None or browser.factory_id != factory.id: guessed = factory.browser_set.filter(active=True, browser_group=request.browser_group, major=request.major, minor=request.minor)[:1] if not len(guessed): guessed = [None] raise ExtraFault(406, u"The browser has not visited the requested website.", request=request, hashkey=hashkey, browser=guessed[0]) # Unpack PNG file and run more checks ppmname = storage.pngtoppm(hashkey) try: magic, width, height = storage.read_pnm_header(ppmname) if request_group.width and request_group.width != width: raise ExtraFault(412, u"The screenshot is %d pixels wide, not %d as requested." % (width, request_group.width), request=request, hashkey=hashkey, browser=browser) if height > width * 4: raise ExtraFault(413, u"The screenshot is too tall (more than 4 times the width).", request=request, hashkey=hashkey, browser=browser) if height < width / 2: raise ExtraFault(414, u"The screenshot is too short (less than half the width).", request=request, hashkey=hashkey, browser=browser) if os.path.exists('/usr/local/etc/pbmgrep'): check_ppm_problems(ppmname, request, hashkey, browser) # Make smaller preview images for size in PREVIEW_SIZES: storage.scale(ppmname, size, hashkey) finally: # Delete temporary PPM file os.unlink(ppmname) # Upload screenshots to Amazon S3 (but not for anonymous users) if hasattr(settings, 'S3_BUCKETS') and request_group.user_id is not None: storage.s3_upload(hashkey) # size='original' for size in PREVIEW_SIZES: storage.s3_upload(hashkey, size) # Save screenshot in database screenshot = Screenshot(hashkey=hashkey, user=request_group.user, website=request_group.website, factory=factory, browser=browser, width=width, height=height, bytes=bytes) screenshot.save() # Close the request close_request(request_id, factory, screenshot) # Update timestamps and estimates now = datetime.now() if request.priority == 0: factory.update_fields(last_upload=now, queue_estimate=(now - request_group.submitted).seconds) else: factory.update_fields(last_upload=now) browser.update_fields(last_upload=now) return hashkey
def upload(http_request, factory, encrypted_password, request, screenshot): """ Submit a multi-page screenshot as a lossless PNG file. Arguments ~~~~~~~~~ * factory_name string (lowercase, normally from hostname) * encrypted_password string (lowercase hexadecimal, length 32) * request int (from requests.poll) * screenshot binary (BASE64-encoded PNG file) See nonces.verify for how to encrypt your password. Return value ~~~~~~~~~~~~ * hashkey string (lowercase hexadecimal, length 32) Users can see the resulting uploaded screenshot at http://browsershots.org/screenshots/hashkey/ """ # Verify authentication nonces.verify(http_request, factory, encrypted_password) request_id = request request = get_or_fault(Request, pk=request_id) request_group = request.request_group # Make sure the request was locked by this factory request.check_factory_lock(factory) # Store and check screenshot file hashkey = storage.save_upload(screenshot) bytes = storage.png_filesize(hashkey) # Make sure the request was redirected by the browser browser = request.browser if browser is None or browser.factory_id != factory.id: guessed = factory.browser_set.filter( active=True, browser_group=request.browser_group, major=request.major, minor=request.minor)[:1] if not len(guessed): guessed = [None] raise ExtraFault(406, u"The browser has not visited the requested website.", request=request, hashkey=hashkey, browser=guessed[0]) # Unpack PNG file and run more checks ppmname = storage.pngtoppm(hashkey) try: magic, width, height = storage.read_pnm_header(ppmname) if request_group.width and request_group.width != width: raise ExtraFault( 412, u"The screenshot is %d pixels wide, not %d as requested." % (width, request_group.width), request=request, hashkey=hashkey, browser=browser) if height > width * 4: raise ExtraFault( 413, u"The screenshot is too tall (more than 4 times the width).", request=request, hashkey=hashkey, browser=browser) if height < width / 2: raise ExtraFault( 414, u"The screenshot is too short (less than half the width).", request=request, hashkey=hashkey, browser=browser) if os.path.exists('/usr/local/etc/pbmgrep'): check_ppm_problems(ppmname, request, hashkey, browser) # Make smaller preview images for size in PREVIEW_SIZES: storage.scale(ppmname, size, hashkey) finally: # Delete temporary PPM file os.unlink(ppmname) # Upload screenshots to Amazon S3 (but not for anonymous users) if hasattr(settings, 'S3_BUCKETS') and request_group.user_id is not None: storage.s3_upload(hashkey) # size='original' for size in PREVIEW_SIZES: storage.s3_upload(hashkey, size) # Save screenshot in database screenshot = Screenshot(hashkey=hashkey, user=request_group.user, website=request_group.website, factory=factory, browser=browser, width=width, height=height, bytes=bytes) screenshot.save() # Close the request close_request(request_id, factory, screenshot) # Update timestamps and estimates now = datetime.now() if request.priority == 0: factory.update_fields(last_upload=now, queue_estimate=(now - request_group.submitted).seconds) else: factory.update_fields(last_upload=now) browser.update_fields(last_upload=now) return hashkey