Пример #1
0
    def add_to_database(self, appstruct):
        """ Extract the fields from the colander validated dictionary,
        add to the database.
        """
        # Get the user
        user = self.add_user_if_required()

        # Create a checkout with the current calibration data
        now = datetime.datetime.now()
        new_checkout = Checkout(serial=appstruct["serial"],
                                timestamp=now)

        calib = Calibration(calibration_name="wavelength",
                            coefficient_0=appstruct["coefficient_0"],
                            coefficient_1=appstruct["coefficient_1"],
                            coefficient_2=appstruct["coefficient_2"],
                            coefficient_3=appstruct["coefficient_3"])

        # Append this new calibration to the checkouts list of
        # calibrations
        new_checkout.calibrations.append(calib)

        # Append to that users' list of checkouts
        user.checkouts.append(new_checkout)
        DBSession.flush() # required to populate the id field
        return new_checkout.id
Пример #2
0
    def checkout_delete(self):
        """ Show a confirmation screen for deleting a checkout. If the
        parameter confirm is present, actually delete and show the
        status.
        """
        checkout_id = self.request.matchdict["checkout_id"]

        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()

        message = "Are you sure you want to delete checkout: %s" \
                   % checkout_id
        if "confirm" not in self.request.params:
            return {"checkout":checkout, "message":message}

        message = "Succesfully deleted checkout: %s" % checkout_id
        DBSession.delete(checkout)

        thumbs_glob = "cookbook/assets/img/thumbnails/%s_*.*" \
                      % checkout_id
        for filename in glob.glob(thumbs_glob):
            log.info("Delete file: %s", filename)
            os.remove(filename)

        return {"message":message}
Пример #3
0
    def generate_calibration_report(self, appstruct, checkout_id):
        """ Use the generator object from the calibration report module
        to create a single page pdf.
        """

        report = EmptyReport()
        report.serial = appstruct["serial"]
        report.coefficient_0 = appstruct["coefficient_0"]
        report.coefficient_1 = appstruct["coefficient_1"]
        report.coefficient_2 = appstruct["coefficient_2"]
        report.coefficient_3 = appstruct["coefficient_3"]
        pdf = WasatchSinglePage(report=report, return_blob=True)

        blob_data = pdf.return_blob()
        log.info("PDF report blob: %s", len(blob_data))
        new_file = File(filename="Calibration_Report.pdf",
                        file_data=blob_data)


        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()
        checkout.files.append(new_file)

        blob_data = pdf.return_thumbnail_blob()
        self.cache_blob(blob_data, checkout_id,
                        "calibration_report_thumbnail.png")
        log.info("thumbnail report blob: %s", len(blob_data))
        new_file = File(filename="calibration_report_thumbnail.png",
                        file_data=blob_data)

        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()
        checkout.files.append(new_file)
Пример #4
0
 def connect_database(self):
     """ Use sqlalchemy to connect directly to the database file on
     disk.
     """
     from sqlalchemy import create_engine
     engine = create_engine("sqlite:///config/cookbook.sqlite")
     DBSession.configure(bind=engine)
     Base.metadata.create_all(engine)
     return DBSession
Пример #5
0
def main(argv=sys.argv):
    """ Create a completely empty database."""
    if len(argv) < 2:
        usage(argv)
    config_uri = argv[1]
    options = parse_vars(argv[2:])
    setup_logging(config_uri)
    settings = get_appsettings(config_uri, options=options)
    engine = engine_from_config(settings, "sqlalchemy.")
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
Пример #6
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, "sqlalchemy.")
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine

    auth_tkt_pol = AuthTktAuthenticationPolicy
    authentication_policy = auth_tkt_pol(auth_policy_secret,
                                         callback=access_verifier,
                                         hashalg='sha512')
    authorization_policy = ACLAuthorizationPolicy()


    config = Configurator(settings=settings,
                          root_factory="cookbook.models.RootFactory",
                          authentication_policy=authentication_policy,
                          authorization_policy=authorization_policy)

    config.include("pyramid_chameleon")

    # Static assets include thumbnails, turn off caching to ensure they
    # are reloaded in a timely fashion
    config.add_static_view("assets", "assets", cache_max_age=1)


    config.add_route("file_add", "/file_add/{checkout_id}")
    config.add_route("file_view", "/file_view/{checkout_id}/{filename}")

    config.add_route("checkout_list", "/checkout_list/")
    config.add_route("checkout_add", "/checkout_add/")
    config.add_route("checkout_view", "/checkout/{checkout_id}")
    config.add_route("checkout_delete",
                     "/checkout_delete/{checkout_id}")


    config.add_route("login", "/login/google")
    config.add_route("logout", "/logout/google")
    config.add_route("user_view", "/user_view/")

    config.add_route("analyze_view", "/analyze/")
    config.add_route("analyze_long_term_view", "/analyze_long_term/")

    config.add_route("serial_view", "/{serial}")
    config.add_route("home_redirect", "/")

    config.scan("cookbook.views")
    return config.make_wsgi_app()
Пример #7
0
    def explode_work_ticket(self, appstruct, checkout_id):
        """ If work_ticket in the filename, create an exploded mosaic
        thumbnail and add that to the database.
        """
        lower_name = appstruct["file_upload"]["filename"].lower()
        if "work_ticket" not in lower_name \
           or ".pdf" not in lower_name:
            return

        file_pointer = appstruct["file_upload"]["fp"]
        file_pointer.seek(0)

        thumg = ThumbnailGenerator(blob=file_pointer.read())
        png_img = thumg.mosaic_thumbnail()

        thumbnail_name = "mosaic_work_ticket_thumbnail.png"
        new_file = File(filename=thumbnail_name, file_data=png_img)
        log.info("assign: %s to %s", new_file.filename, checkout_id)

        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()
        checkout.files.append(new_file)

        # Save the thumbnail to disk
        self.cache_blob(png_img, checkout_id,
                        "mosaic_work_ticket_thumbnail.png")
Пример #8
0
    def file_add(self):
        """ Expect a valid checkout id, add a file to the file system
        and store retrieval values in database.
        """
        # require a known checkout id
        checkout_id = self.request.matchdict["checkout_id"]
        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()

        form = Form(NewFileSchema(), buttons=("submit",))
        if "submit" in self.request.POST:
            log.info("File submit: %s", self.request.POST)
            controls = self.request.POST.items()

            try:
                appstruct = form.validate(controls)

                self.assign_filename_if_selected(appstruct)
                chk_id = self.file_add_to_database(appstruct)
                self.explode_work_ticket(appstruct, chk_id)
                self.cache_thumbnails(appstruct, chk_id)

                location = self.request.route_url("checkout_view",
                                                  checkout_id=chk_id)
                return HTTPFound(location=location)

            except ValidationFailure as exc:
                log.warn("File Validation failure")
                checkout = {"serial":"invalid", "id":"invalid",
                            "timestamp":"invalid"}
                return {"form":exc.render(), "checkout":checkout}

        return {"form":form.render(), "checkout":checkout}
Пример #9
0
    def add_user_if_required(self):
        """ Try and find that user in the database, add it if required.
        Requires the user to be authenticated.
        """
        useremail = self.request.authenticated_userid

        dbqry = DBSession.query(User)
        checkout = dbqry.filter(User.fullemail == useremail).first()
        if checkout is None:
            log.warn("User does not exist, adding: %s", useremail)
            new_user = User(fullemail=useremail, fullname="testname")
            DBSession.add(new_user)

            checkout = dbqry.filter(User.fullemail == useremail).first()

        return checkout
Пример #10
0
    def build_stats(self):
        """ Classify and count checkouts based on their serial number.
        """
        dbqry = DBSession.query(Checkout).filter
        cobra = dbqry(Checkout.serial.like("C-%")).count()
        stroker_785l = dbqry(Checkout.serial.like("S785L%")).count()
        stroker_785c = dbqry(Checkout.serial.like("S785C%")).count()
        ventana = dbqry(Checkout.serial.like("V%")).count()

        # Other is total count - sum of all found groups
        db_total = DBSession.query(Checkout).count()
        other = db_total - (cobra + stroker_785l + ventana +
                            stroker_785c)


        return dict(cobra=cobra, stroker_785l=stroker_785l, other=other,
                    stroker_785c=stroker_785c, ventana=ventana,
                    db_total=db_total)
Пример #11
0
    def file_add_to_database(self, appstruct):
        """ Write the file upload to the database. Append it to the list
        of files for the checkout.
        """
        #log.info("full appstruct: %s", appstruct)
        file_pointer = appstruct["file_upload"]["fp"]
        file_pointer.seek(0)

        filename = appstruct["file_upload"]["filename"]
        filename = self.strip_test_delimiters(filename)

        new_file = File(filename=filename,
                        file_data=file_pointer.read())
        #log.info("Obj: %r", file_pointer)
        log.info("assign: %s", new_file.filename)


        checkout_id = self.request.matchdict["checkout_id"]
        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()
        checkout.files.append(new_file)

        DBSession.flush() #required to get checkout id
        return checkout.id
Пример #12
0
    def analyze_long_term_view(self):
        """ All statistics from the db
        """
        dbqry = DBSession.query(Checkout).filter


        # Gather a list of the previous six months including year, use
        # mktime to roll over the year where applicable. From:
        # http://stackoverflow.com/questions/6576187/\
        # get-year-month-for-the-last-x-months
        month_history = 32
        now = time.localtime()
        month_list = []
        month_names = []
        for month in range(month_history):
            make_time = time.mktime((now.tm_year, now.tm_mon - month,
                                     1, 0, 0, 0, 0, 0, 0)
                                   )

            new_time = time.localtime(make_time)

            # Convert the month to two digit
            loc_mon = "%s" % new_time.tm_mon
            if len(loc_mon) == 1:
                loc_mon = "0%s" % loc_mon

            # Use a LIKE query on the timestamp value
            time_str = "%s-%s%%" % (new_time.tm_year, loc_mon)
            count = dbqry(Checkout.timestamp.like(time_str)).count()

            month_list.insert(0, str(count))
            month_names.insert(0, calendar.month_name[new_time.tm_mon])

        # Create the javascript text line
        month_string = ",".join(month_list)
        month_data = "data : [%s]," % month_string

        # Javascript axis label
        month_words = "\", \"".join(month_names)
        month_labels = "labels: [\"%s\",]," % month_words

        # Build the statistics by class
        classes = self.build_stats()
        prefix_groups = self.build_prefix_groups()

        return dict(month_data=month_data, month_labels=month_labels,
                    classes=classes, prefix_groups=prefix_groups,
                   )
Пример #13
0
    def generate_qr_label(self, appstruct, checkout_id):
        """ Use the stickercode generation code inline from the
        StickerCode project. Generate a temporary qr label on disk, then
        load it into a db blob.
        """
        lbl = QL700Label(domain="http://waspho.com",
                         serial=appstruct["serial"],
                         return_blob=True)

        blob_data = lbl.return_blob()
        self.cache_blob(blob_data, checkout_id, "qr_label.png")
        new_file = File(filename="qr_label.png", file_data=blob_data)

        log.info("QR Llabel blob: %s", len(blob_data))

        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()
        checkout.files.append(new_file)
Пример #14
0
    def serial_view(self):
        """ Get the most recent checkout with the specified serial
        number. Send to view by checkout to return desired info.
        """
        serial = self.request.matchdict["serial"]
        log.info("Find: %s", serial)

        dbqry = DBSession.query(Checkout)
        order_by = dbqry.order_by(Checkout.timestamp.desc())
        last_id = order_by.filter(Checkout.serial == serial).first()

        if last_id is None:
            log.info("Can't find: %s", serial)
            return HTTPNotFound()

        log.info("Checkout id assigned: %s for %s", last_id.id, serial)
        self.request.matchdict["checkout_id"] = last_id.id
        return self.checkout_view()
Пример #15
0
    def file_view(self):
        """ Find a file matching the checkout id and filename passed
        into matchdict. Otherwise return failures.
        """

        # require a known checkout id
        checkout_id = self.request.matchdict["checkout_id"]

        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).one()

        filename = self.request.matchdict["filename"]

        #log.warn("Find: %s, %s as %s", checkout_id, filename,
                 #self.request.authenticated_userid)
        #log.info("Params: %s", self.request.params)

        file_data = self.database_or_placeholder(checkout, filename)
        file_data = self.resize_if_params(file_data)

        return self.build_file_response(file_data, filename)
Пример #16
0
    def insert_file(self, checkout_id, full_name, short_name):
        """ Open the file on disk, write the contents to the database.
        """
        log.debug("Insert %s into checkout: %s", full_name, checkout_id)
      
        if not os.path.exists(full_name):
            log.warn("%s file does not exist", full_name)
            return

        file_pointer = open(full_name)
        file_pointer.seek(0)


        with transaction.manager:
            new_file = File(filename=short_name,
                            file_data=file_pointer.read())

            dbqry = DBSession.query(Checkout)
            checkout = dbqry.filter(Checkout.id == checkout_id).one()
            checkout.files.append(new_file)

            log.debug("Added %s to checkout: %s", short_name, checkout_id)
Пример #17
0
    def build_prefix_groups(self):
        """ Create a list of 1-N letter prefixes of all the serial
        numbers in the database. This provides a primitive breakdown of
        device classes.
        """
        dbqry = DBSession.query(Checkout).all()

        from collections import defaultdict
        prefixes = defaultdict(int)

        prefixes = {}
        for item in dbqry:
            start = item.serial[0:2]

            if start in prefixes:
                prefixes[start] += 1
            else:
                prefixes[start] = 1


        print "All group prefixes: %s" % prefixes
        return prefixes
Пример #18
0
    def checkout_list(self):
        """ Return entire list of checkouts from the database. If page
        parameter is specified, show just a slice of the results.
        """
        dbqry = DBSession.query(Checkout).order_by
        checkouts = dbqry(Checkout.timestamp.desc()).all()

        # If page not specified, set range to full extent
        page_num = 1
        if "page" not in self.request.params:
            start = 0
            stop = len(checkouts)
        else:
            page_length = 10
            page_num = int(self.request.params["page"])
            start = page_length * (page_num-1)
            stop = start + page_length

        # Accept the goodness that a slice out of range on a query
        # return does not throw an exception, it returns zero devices or
        # the last N in the list
        checkouts = checkouts[start:stop]

        return {"checkouts":checkouts}
Пример #19
0
    def checkout_view(self):
        """ Build a dictionary of template-expected values of the
        checkout, user and file data model.
        """

        checkout_id = self.request.matchdict["checkout_id"]
        dbqry = DBSession.query(Checkout)
        checkout = dbqry.filter(Checkout.id == checkout_id).first()
        log.info("View checkout %s", checkout.serial)

        allow_files = []
        for item in checkout.files:
            #log.info("Checkout file: %s", item.filename)
            if self.filename_allowed(item.filename):
                allow_files.append(item)
            else:
                log.warn("Not showing file: %s", item.filename)

        link_files = {}
        bad_names = ["high_camera_image", "low_camera_image",
                     "qr_label", "Calibration_Report",
                     "calibration_report_thumbnail",
                     "work_ticket",]
        for item in allow_files:
            found = 0
            for check_str in bad_names:
                if check_str in item.filename:
                    #log.info("Not listing file %s", item.filename)
                    found += 1

            if found == 0:
                link_files[item.filename] = len(item.file_data)


        return {"checkout":checkout, "files":allow_files,
                "link_files":link_files}