コード例 #1
0
    def test_api_products_edit(self):
        """
        Tests the "api_products_edit" API method.
        Success conditions :
        - The API can't be accessed without being logged
        - Perfoms correctly ADD / EDIT  operations
        """
        with webapp.test_client() as app:
            # Tests access without being authenticated
            response = app.get('/api/products_edit/foo/bar')
            assert response.status_code == 401

            # Authenticate
            data = {'password': self.password_raw}
            response = app.post('/', data=data, follow_redirects=True)

            # Test : add
            barcode = '1000000000001'
            name = 'foobar'

            response = app.get('/api/products_edit/' + barcode + '/' + name)
            entry = models.Products().get_item(barcode)
            assert response.status_code == 200
            assert entry
            assert entry['barcode'] == barcode
            assert entry['name'] == name

            # Test : edit
            name = 'barfoo'
            response = app.get('/api/products_edit/' + barcode + '/' + name)
            entry = models.Products().get_item(barcode)
            assert response.status_code == 200
            assert entry
            assert entry['barcode'] == barcode
            assert entry['name'] == name
コード例 #2
0
    def setup_method(self):
        """
        Setup method :
        - Sets database to test mode and populates it
        - Launches Flask in test mode
        """
        # Database
        Database.TEST_MODE = True
        Database.on()

        # Create test database
        models.Params(autoload=False).create_table()
        models.Products().create_table()
        models.Groceries().create_table()

        # Params : user config
        self.password_raw = 'abcdefg'
        self.password_sha1 = bytearray(self.password_raw, encoding='utf-8')
        self.password_sha1 = hashlib.sha1(self.password_sha1).hexdigest()
        params = models.Params()
        params.add_item('user_password', self.password_sha1)
        params.add_item('lang', 'en')

        # Products : 1 sample item
        self.default_barcode = '1234567890123'
        self.default_name = 'Lorem Ipsum'
        models.Products().add_item(self.default_barcode, self.default_name,
                                   True)

        # Groceries : 1 sample item
        models.Groceries().add_item(self.default_barcode, 1)
コード例 #3
0
def api_products_list_key(api):
    """
    API method : Gets all items from the products table.
    Outputs JSON.
    Returns the latest version of the grocery list.
    JSON format :
    - {"status": ..., "items" ...}
    Possible return status :
    - OK (200)
    """
    # AJAX Auth check
    Database.on()
    # Load parameters
    params = models.Params()
    # Database : end connection
    # (open it only when needed because this program is meant to be shutdown harshly)
    Database.off()
    # Database access
    api_key = params.api_key
    if api_key != api:
        return render_template('json.html', json="{}"), 401
    # Output
    data = {"status": "OK", "items": []}

    # Get info
    Database.on()
    data['items'] = models.Products().get_list()
    Database.off()
    # Render
    return render_template('json.html', json=json.dumps(data))
コード例 #4
0
    def test_api_products_list(self):
        """
        Tests the "api_products_list" API method.
        Success conditions :
        - The API can't be accessed without being logged : HTTP 401
        - Returns HTTP 200 when logged with the expected content as JSON
        """
        with webapp.test_client() as app:
            # Tests access without being authenticated
            response = app.get('/api/products_list')
            assert response.status_code == 401

            # Authenticate
            data = {'password': self.password_raw}
            response = app.post('/', data=data, follow_redirects=True)

            # Does the API returns the expected data ?
            # JSON "item" entry must contain the same thing as Products > get_list
            response = app.get('/api/products_list')

            expected_data = models.Products().get_list()
            given_data = str(response.data, encoding='utf-8')
            given_data = json.loads(given_data)
            given_data = given_data['items'].keys()

            assert response.status_code == 200
            assert set(expected_data) == set(given_data)
コード例 #5
0
ファイル: test_models.py プロジェクト: pnposch/jean-pierre
    def setup_method(self):
        """
        Creates a dummy database for tests
        """
        # Creates database
        Database.TEST_MODE = True
        Database.on()
        self.cursor = Database.CURSOR

        # Create tables
        self.params = models.Params(autoload=False)
        self.products = models.Products()
        self.groceries = models.Groceries()
        self.params.create_table()
        self.products.create_table()
        self.groceries.create_table()

        # Insert dummy data
        self.default_barcode = '123456789ABCD'
        self.default_name = 'Lorem Ipsum'
        self.default_pic = 'PIC'

        self.params.add_item('foo', 'bar')
        self.products.add_item(self.default_barcode, self.default_name,
                               self.default_pic)
        self.groceries.add_item(self.default_barcode, 1)
コード例 #6
0
 def __init__(self):
     #define the cursor of pymysql to manipulate datas
     self.cursor = connect.cursor
     # creating objects that are imported from models
     self.cat = models.Cat()
     self.prods = models.Products()
     self.favs = models.Favorits()
     self.my_base = models.MyBase()
     #Geting the api's link of a specific categorie mentionned "creat_url method"
     self.req = requests.get(self.Creat_url('saucissons'))
コード例 #7
0
 def __init__(self):
     #define the cursor of pymysql to manipulate datas
     self.cursor = connect.cursor
     #Geting all classes indeed
     self.cat = models.Cat()
     self.prods = models.Products()
     self.app = views.MyApp()
     #self.app.win.mainloop()
     #creat a tuple of categories value to add in the comobox of the view
     self.cats_val = ()
コード例 #8
0
def api_products_edit(barcode, name):
    """
    API method : Add/Edit/Delete items from the products database.
    If an item doesn't exist, it will be created.
    Outputs JSON.
    :param barcode: An unknown product barcode
    :param name: The new product's name
    JSON format :
    - {"status": ..., "barcode" ..., "name": ...}
    Possible return status :
    - ADDED (200) / ADD ERROR (400)
    - EDITED (200) / EDIT ERROR (400)
    """
    # AJAX Auth check
    if not ('is_logged' in session and session['is_logged']):
        return render_template('json.html', json="{}"), 401

    # Remove unwanted chars
    to_escape = ['"', "<", ">", "&", "'"]
    for char in to_escape:
        barcode = barcode.replace(char, '')
        name = name.replace(char, '')

    # Output
    data = {"status": "", "barcode": barcode, "name": name}

    # Database access
    Database.on()
    products_db = models.Products()

    # Try to get the entry in the grocery list
    exists = products_db.get_item(barcode)
    status_code = 200

    # If it doesn't exist : add it
    if not exists:
        try:
            products_db.add_item(barcode, name, False)
            data['status'] = 'ADDED'
        except Exception as trace:
            data['status'] = 'ADD ERROR'
            status_code = 400
    # If it exists : edit it
    else:
        try:
            products_db.edit_item(barcode, name, exists['pic'])
            data['status'] = 'EDITED'
        except Exception as trace:
            data['status'] = 'EDIT ERROR'
            status_code = 400

    # Database : off and outputs data
    Database.off()
    return render_template('json.html', json=json.dumps(data)), status_code
コード例 #9
0
 def __init__(self):
     # Create instances
     self.win = tk.Tk()
     self.win.geometry( "820x720" )
     self.win.resizable(0,0)
     self.win.iconbitmap(r'C:\Users\boukr\Desktop\here\GUI-OFF-P5\logo.ico')
     #Attributs of the models's Classes
     self.cat = models.Cat()
     self.prods = models.Products()
     self.fav = models.Favorits()
     self.cursor = connect.cursor
     # Add a title
     self.win.title("OpenFoodFacts")
     #creat widgets
     self.createWidgets()
     #tuple of products combobox
     self.prods_val = ()
コード例 #10
0
ファイル: test_utils.py プロジェクト: pnposch/jean-pierre
    def setup_method(self):
        """
        Setup method, creates a dummy database
        """
        # Creates test database
        Database.TEST_MODE = True
        Database.on()
        self.cursor = Database.CURSOR

        # Create tables
        models.Params(autoload=False).create_table()
        models.Products().create_table()
        models.Groceries().create_table()

        # Defaults barcodes
        self.valid_barcode = '3017620424403'
        self.invalid_barcode = '123456789ABCD'

        # Deconnects database to let threads use them
        Database.off()
コード例 #11
0
    def test_api_products_delete(self):
        """
        Tests the "api_products_delete" API method.
        Success conditions :
        - The API can't be accessed without being logged
        - Perfoms correctly DELETE operations
        """
        with webapp.test_client() as app:
            # Tests access without being authenticated
            response = app.get('/api/products_edit/foo/bar')
            assert response.status_code == 401

            # Authenticate
            data = {'password': self.password_raw}
            response = app.post('/', data=data, follow_redirects=True)

            # Test : Delete
            response = app.get('/api/products_delete/' + self.default_barcode)
            assert response.status_code == 200
            assert not models.Products().get_item(self.default_barcode)
コード例 #12
0
def groceries():
    """
    Shows GROCERIES template if the user is logged.
    """
    # Auth check
    if 'is_logged' not in session or not session['is_logged']:
        return redirect(url_for('login'))

    # Database access + loads basic info
    Database.on()
    lang = utils.Lang(models.Params().lang)
    items = models.Products().get_list()
    Database.off()

    # Prepare template data
    data = {
        'lang': lang.__dict__,
        'body_class': 'groceries',
        'products_list': items
    }

    # Return template
    return render_template('groceries.html', **data)
コード例 #13
0
def api_products_delete(barcode):
    """
    API method : Deletes an item from the products table.
    Outputs JSON.
    Returns the latest version of the grocery list.
    JSON format :
    - {"status": ...}
    Possible return status :
    - OK (200)
    - DELETE ERROR (400)
    """
    # AJAX Auth check
    if not ('is_logged' in session and session['is_logged']):
        return render_template('json.html', json="{}"), 401

    # Remove unwanted chars
    to_escape = ['"', "<", ">", "&", "'"]
    for char in to_escape:
        barcode = barcode.replace(char, '')

    # Output
    data = {"status": "OK"}

    # Try to delete
    Database.on()
    try:
        models.Products().delete_item(barcode)
        data['status'] = 'OK'
        status_code = 200
    except Exception as trace:
        data['status'] = 'DELETE ERROR'
        status_code = 400
    Database.off()

    # Render
    return render_template('json.html', json=json.dumps(data)), status_code
コード例 #14
0
def api_products_list():
    """
    API method : Gets all items from the products table.
    Outputs JSON.
    Returns the latest version of the grocery list.
    JSON format :
    - {"status": ..., "items" ...}
    Possible return status :
    - OK (200)
    """
    # AJAX Auth check
    if not ('is_logged' in session and session['is_logged']):
        return render_template('json.html', json="{}"), 401

    # Output
    data = {"status": "OK", "items": []}

    # Get info
    Database.on()
    data['items'] = models.Products().get_list()
    Database.off()

    # Render
    return render_template('json.html', json=json.dumps(data))
コード例 #15
0
ファイル: config.py プロジェクト: pnposch/jean-pierre
    def execute(cls, language='en'):
        """
        Creates database, tables and ask for user parameters.
        :param language: Set language for this menu
        :type language: str
        Defined parameters :
        - buzzer_on
        - buzzer_port
        - camera_res_x
        - camera_res_y
        - user_password
        - lang
        """
        # Language file
        lang = Lang(language)

        # Intro
        print("-" * 80)
        print(lang.config_intro)
        print("-" * 80)

        # Create / connects to the database
        Database.on()
        print(lang.config_database_created)

        # Create table : params
        params = models.Params(autoload=False)
        params.create_table()
        print(lang.config_table_params_set)

        # Create table : groceries
        groceries = models.Groceries()
        groceries.create_table()
        print(lang.config_table_groceries_set)

        # Create table : products
        products = models.Products()
        products.create_table()
        print(lang.config_table_products_set)

        # Set language
        params.delete_item('lang')
        language = input(lang.config_language_set)
        if language not in Lang.available():
            language = 'en'
        params.add_item('lang', language)

        # Ask for : use buzzer / on which port ?
        params.delete_item('buzzer_on')
        params.delete_item('buzzer_port')
        buzzer_on = input(lang.config_buzzer_on)

        # Yes
        if buzzer_on.upper() == "Y":
            buzzer_port = input(lang.config_buzzer_port)
            if re.findall('([0-9]+)', buzzer_port):
                params.add_item('buzzer_on', '1')
                params.add_item('buzzer_port', buzzer_port)
            else:
                print(lang.config_buzzer_invalid_port)
                params.add_item('buzzer_on', '0')
                params.add_item('buzzer_port', '0')
        # No
        else:
            params.add_item('buzzer_on', '0')
            params.add_item('buzzer_port', '0')

        # Ask for : camera resolution
        params.delete_item('camera_res_x')
        params.delete_item('camera_res_y')

        for axis in ['x', 'y']:
            if axis == 'x':
                question = lang.config_camera_res_x
            else:
                question = lang.config_camera_res_y

            resolution = input(question)
            if not re.findall('([0-9]+)', resolution):
                resolution = 500

            params.add_item('camera_res_{}'.format(axis), resolution)

        # Ask for : user password
        params.delete_item('user_password')
        user_password = getpass.getpass(lang.config_password)
        if not user_password:
            user_password = '******'
        user_password = bytearray(user_password, encoding='utf-8')
        user_password = hashlib.sha1(user_password).hexdigest()
        params.add_item('user_password', user_password)

        # Close connection to the database
        Database.off()

        # Bye !
        print(lang.config_done)
コード例 #16
0
    def execute(cls, language='en'):
        """
        Creates database, tables and ask for user parameters.
        :param language: Set language for this menu
        :type language: str
        Defined parameters :
        - buzzer_on
        - buzzer_port
        - camera_res_x
        - camera_res_y
        - user_password
        - lang
        - api_key
        """
        # Language file
        lang = Lang(language)

        # Intro
        print("-" * 80)
        print(lang.config_intro)
        print("-" * 80)

        # Create / connects to the database
        Database.on()
        print(lang.config_database_created)

        # Create table : params
        params = models.Params(autoload=False)
        params.create_table()
        print(lang.config_table_params_set)

        # Create table : groceries
        groceries = models.Groceries()
        groceries.create_table()
        print(lang.config_table_groceries_set)

        # Create table : products
        products = models.Products()
        products.create_table()
        print(lang.config_table_products_set)

        # Set language
        params.delete_item('lang')
        language = input(lang.config_language_set)
        if language not in Lang.available():
            language = 'en'
        params.add_item('lang', language)

        # Ask for : use buzzer / on which port ?
        params.delete_item('buzzer_on')
        params.delete_item('buzzer_port')
        buzzer_on = input(lang.config_buzzer_on)

        # Yes
        if buzzer_on.upper() == "Y":
            buzzer_port = input(lang.config_buzzer_port)
            if re.findall('([0-9]+)', buzzer_port):
                params.add_item('buzzer_on', '1')
                params.add_item('buzzer_port', buzzer_port)
            else:
                print(lang.config_buzzer_invalid_port)
                params.add_item('buzzer_on', '0')
                params.add_item('buzzer_port', '0')
        # No
        else:
            params.add_item('buzzer_on', '0')
            params.add_item('buzzer_port', '0')

        # Ask for : camera resolution
        params.delete_item('camera_res_x')
        params.delete_item('camera_res_y')

        for axis in ['x', 'y']:
            if axis == 'x':
                question = lang.config_camera_res_x
            else:
                question = lang.config_camera_res_y

            resolution = input(question)
            if not re.findall('([0-9]+)', resolution):
                resolution = 500

            params.add_item('camera_res_{}'.format(axis), resolution)

        # Ask for : user password
        params.delete_item('user_password')
        user_password = getpass.getpass(lang.config_password)
        if not user_password:
            user_password = '******'
        user_password = bytearray(user_password, encoding='utf-8')
        user_password = hashlib.sha1(user_password).hexdigest()
        params.add_item('user_password', user_password)

        import random
        random = random.SystemRandom()

        def get_random_string(length=12,
                              allowed_chars='abcdefghijklmnopqrstuvwxyz'
                              'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):

            return ''.join(random.choice(allowed_chars) for i in range(length))

        def get_secret_key():
            """
            Create a random secret key.
 
            Taken from the Django project.
            """
            chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$^*(-_=+)'
            return get_random_string(24, chars)

        # Ask for : api key
        params.delete_item('api_key')
        api_key = getpass.getpass(lang.config_api)
        if not api_key:
            api_key = (get_secret_key())
        params.add_item('api_key', api_key)
        print('Api-Key:  ' + api_key)

        # Close connection to the database
        Database.off()

        # Bye !
        print(lang.config_done)
コード例 #17
0
def api_products_editt_key(api, barcode, name):
    """
    API method : Add/Edit/Delete items from the products database.
    If an item doesn't exist, it will be created.
    Outputs JSON.
    :param barcode: An unknown product barcode
    :param name: The new product's name
    JSON format :
    - {"status": ..., "barcode" ..., "name": ...}
    Possible return status :
    - ADDED (200) / ADD ERROR (400)
    - EDITED (200) / EDIT ERROR (400)
    """
    # AJAX Auth check
    Database.on()
    # Load parameters
    params = models.Params()
    # Database : end connection
    # (open it only when needed because this program is meant to be shutdown harshly)
    Database.off()
    # Database access
    api_key = params.api_key
    if api_key == api:
        session['is_logged'] = True
    #   return redirect(url_for('groceries'))
    # Remove unwanted chars
    to_escape = ['"', "<", ">", "&", "'"]
    for char in to_escape:
        barcode = barcode.replace(char, '')
        name = name.replace(char, '')

    # Output
    data = {"status": "", "barcode": barcode, "name": name}

    # Database access
    Database.on()
    products_db = models.Products()

    # Try to get the entry in the grocery list
    exists = products_db.get_item(barcode)
    status_code = 200

    # If it doesn't exist : add it
    if not exists:
        try:
            products_db.add_item(barcode, name, False)
            data['status'] = 'ADDED'
        except Exception as trace:
            data['status'] = 'ADD ERROR'
            status_code = 400
    # If it exists : edit it
    else:
        try:
            products_db.edit_item(barcode, name, exists['pic'])
            data['status'] = 'EDITED'
        except Exception as trace:
            data['status'] = 'EDIT ERROR'
            status_code = 400

    # Database : off and outputs data
    Database.off()
    return render_template('json.html', json=json.dumps(data)), status_code
コード例 #18
0
def api_groceries_edit(barcode, quantity):
    """
    API method : Add/Edit/Delete items from the grocery list.
    If the item doesn't exist, it will be created.
    Outputs JSON.
    :param barcode: A known product barcode
    :param quantity: The quantity defines the operation (quantity 0 = delete)
    JSON format :
    - {"status": ..., "barcode" ..., "quantity": ...}
    Possible return status :
    - PRODUCT NOT FOUND (404)
    - ADDED (200) / ADD ERROR (400)
    - EDITED (200) / EDIT ERROR (400)
    - DELETED (200) / DELETE ERROR (400)
    """
    # AJAX Auth check
    if not ('is_logged' in session and session['is_logged']):
        return render_template('json.html', json="{}"), 401

    # Remove unwanted chars
    to_escape = ['"', "<", ">", "&", "'"]
    for char in to_escape:
        barcode = barcode.replace(char, '')
    quantity = int(quantity)

    # Output
    data = {"status": "", "barcode": barcode, "quantity": quantity}

    # Database access
    Database.on()
    products_db = models.Products()
    groceries_db = models.Groceries()

    # Try to get the product associated with the barcode
    product = products_db.get_item(barcode)

    if not product:
        data['status'] = 'PRODUCT NOT FOUND'
        return render_template('json.html', json=json.dumps(data)), 404

    # Try to get the entry in the grocery list
    exists = groceries_db.get_item(barcode)
    status_code = 200

    # If it doesn't exist : add it
    if not exists:
        try:
            if not quantity:
                quantity = 1
            groceries_db.add_item(barcode, quantity)
            data['status'] = 'ADDED'
        except Exception as trace:
            data['status'] = 'ADD ERROR'
            status_code = 400
    # If it exists :
    else:
        # If quantity = 0 : Delete
        if quantity <= 0:
            try:
                groceries_db.delete_item(barcode)
                data['status'] = 'DELETED'
            except Exception as trace:
                data['status'] = 'DELETE ERROR'
                status_code = 400
        # If quantity > 0 : Edit quantity
        else:
            try:
                groceries_db.edit_item(barcode, abs(quantity))
                data['status'] = 'EDITED'
            except Exception as trace:
                data['status'] = 'EDIT ERROR'
                status_code = 400

    # Database : off and outputs data
    Database.off()
    return render_template('json.html', json=json.dumps(data)), status_code
コード例 #19
0
ファイル: findproduct.py プロジェクト: pnposch/jean-pierre
    def run(self):
        """
        Fetch, gathers, insert product infos and adds it to the grocery list.
        Threaded
        :rtype: bool
        """
        with FindProduct.LOCK:
            # Database connection
            Database.on()

            # Marks
            found = False
            cache = False
            products = models.Products()
            groceries = models.Groceries()
            message = ""

            # Try to find the product in the local products database
            cache = products.get_item(self.barcode)
            if cache:
                found = True
                self.name = cache['name']
                self.barcode = cache['barcode']
                message += "{barcode} : Found {name} from local products database.\n"

            # If not found locally : Try to find the product in the OpenFoodFacts API
            if not found:
                # If found on OpenFoodFacts : add it to the local database
                if self.__fetch_openfoodfacts():
                    found = True
                    products.add_item(self.barcode, self.name, self.pic)
                    message += "{barcode} : Found {name} from OpenFoodFacts.\n"
                    message += "{barcode} : {name} added to cache.\n"
                else:
                    message += "{barcode} : Not found locally nor on OpenFoodFacts.\n"

            # If not found : add as unknown item (name = ???)
            if not found:
                self.name = '???'
                self.pic = False
                products.add_item(self.barcode, self.name, self.pic)
                message += "{barcode} : Unknown product added to the database.\n"

            # If the product's already present in the grocery list: increase its quantity by 1
            previous = groceries.get_item(self.barcode)
            if previous:
                self.quantity = previous['quantity'] + 1
                groceries.edit_item(self.barcode, self.quantity)
                message += "{barcode} : {quantity} {name} now in grocery list.\n"
            # Otherwise : add it
            else:
                groceries.add_item(self.barcode, 1)
                message += "{barcode} : 1 {name} added to the grocery list.\n"

            # Disconnect the database, allowing it to be used by another thread
            Database.off()

            # Print message
            message = message.format(barcode=self.barcode,
                                     name=self.name,
                                     quantity=self.quantity)
            print(message)