Rupert  Beatty

Rupert Beatty

1671628020

How to Manage Sessions Over HTTPS with Node.js and Vue.js

A long time ago when I had been exploring session management in Node.js, I had written a tutorial titled, Session Management in Your Express.js Web Application. This was a basic tutorial that is still very functional today, however little things have changed since then when it comes to how the web works. For example, in 2015 HTTPS was never a requirement and we weren’t exposed to all the frontend web frameworks that exist today.

When you start introducing things into your web applications such as HTTPS or micro-services that operate on different origins or ports, or frontend frameworks, session management can get a little more complicated. We’re going to see how to maintain a session for a user using Node.js with Express.js on our backend and Vue.js on our frontend, in this tutorial.

Before getting too involved, there is something to note first. This particular tutorial will be using HTTPS with self-signed certificates. How you get HTTPS working within your application or what kind of certificate you try to use is up to you. However, if you need a bump in the right direction, I had written a tutorial titled, Create a Self-Signed Certificate for Node.js on MacOS, that might help. The assumption is that you also have access to the certificate files used.

Building an HTTPS Secured Node.js Application with Session Management

Because our sessions will be maintained server-side, we need to first create our backend application with Node.js and Express.js. Assuming you have Node.js installed, execute the following commands:

npm init -y
npm install express --save
npm install express-session --save
npm install cors --save
npm install body-parser --save
npm install uuid --save

While the above commands didn’t have to be split into numerous commands, what they’ll do is create a new project with the necessary dependencies. While they are all important for this project, the express-session and cors packages are the most important.

To get us up to speed with the previous article I wrote around HTTPS, create an app.js file within your project and include the following JavaScript code:

const Express = require("express");
const BodyParser = require("body-parser");
const Cors = require("cors");
const HTTPS = require("https");
const FS = require("fs");
const UUID = require("uuid");
const session = require("express-session");

var app = Express();

app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));

app.get("/session", (request, response, next) => { });
app.post("/session", (request, response, next) => { });

HTTPS.createServer({
    key: FS.readFileSync("server.key"),
    cert: FS.readFileSync("server.cert")
}, app).listen(443, () => {
    console.log("Listening at :443...");
});

You’ll notice that we have started our server with HTTPS, so the assumption is that you already have your certificates figured out. This example will have two endpoints. The first endpoint will set the session and return it to the user and the second endpoint will validate user data against the session. What I’m trying to demonstrate is that the session persists across numerous HTTP requests.

With our boilerplate code in place, let’s configure the session management in our backend. You’ll want your code to look like the following:

app.use(session({ secret: "thepolyglotdeveloper", cookie: { secure: true, maxAge: 60000 }, saveUninitialized: true, resave: true }));
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));

Notice that we are setting a secret for the session, making it mandatory that we are secured with HTTPS and creating the session even before we try to use it. Probably the most important part here is that we are saying it is secure because both the Node.js API and the client frontend will be using HTTPS.

The first endpoint that the user will encounter will be a consumption endpoint:

app.get("/session", (request, response, next) => {
    request.session.example = UUID.v4();
    response.send({ id: request.session.example });
});

When the user requests data, the session will store a UUID value and return it back to the user. The goal here is to have the user send this data back to be validated and if it doesn’t match, we’ll throw an error. To do the validation, we can create the following endpoint:

app.post("/session", (request, response, next) => {
    if(request.body.session != request.session.example) {
        return response.status(500).send({ message: "The data in the session does not match!" });
    }
    response.send({ message: "Success!" });
});

The logic in our application is not intended to be complex. We just want to show that the session data persists across numerous requests. Do note that the session is being stored in memory on the server and that there are numerous ways to store a session. A better solution might be to store it in a database instead, so that way if the application needs to be restarted, the sessions are not cleared.

As of right now we have an API with sessions. However, there is one important thing that we’re missing that is particularly important when using micro-services. Typically our API and our client frontend will not be on the same domain or port which would create problems with cross origin resource sharing (CORS). We need to create a whitelist of origins that are allowed to send session information:

app.use(session({ secret: "thepolyglotdeveloper", cookie: { secure: true, maxAge: 60000 }, saveUninitialized: true, resave: true }));
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));
app.use(Cors({ origin: ["https://localhost:2015"], credentials: true }));

Notice that we are using the cors package to define the possible origins and we are saying that credentials can be passed. By default the client will not be able to send session information in the request which would give our API problems. What would happen is the session would not persist between requests for a particular user because the user data isn’t being passed.

At this point in time our API should be functional and we’re ready to start designing our frontend experience.

Building a Client Frontend with the Vue.js JavaScript Framework

When it comes to the frontend technology, it doesn’t really matter, but for this example we’re going to use Vue.js. The assumption is that you have the Vue CLI installed, configured, and ready to go. From the command line, execute the following to create a new project:

vue create session-vue

The CLI will ask you a few questions, but you can use the defaults for this example. We’re only going to be making changes to the project’s src/components/HelloWorld.vue file. If you want, you can change the components to have more friendly names or change the styling, but it is out of the scope of what we want to accomplish.

Since we will be making HTTP requests, we’re going to need to install the axios package. This can be done by executing the following:

npm install axios --save

There are other ways to make HTTP requests in Vue.js, but we are going to stick with the axios way. You can view more information on consuming API data in a previous tutorial I wrote titled, Consume Remote API Data via HTTP in a Vue.js Web Application.

Open the project’s src/components/HelloWorld.vue file and include the following code:

<template>
    <div class="hello">
        <input type="text" v-model="id" />
        <button v-on:click="validate()">Send</button>
    </div>
</template>

<script>
    import axios from "axios";
    export default {
        name: 'HelloWorld',
        data() {
            return {
                id: ""
            };
        },
        mounted() {
            axios({ method: "GET", "url": "https://localhost/session", withCredentials: true }).then(result => {
                this.id = result.data.id;
            }, error => {
                console.error(error.response.data);
            });
        },
        methods: {
            validate() {
                axios({ method: "POST", "url": "https://localhost/session", data: { session: this.id }, headers: { "content-type": "application/json" }, withCredentials: true }).then(result => {
                    alert(JSON.stringify(result.data));
                }).catch(error => {
                    console.error(error.response.data);
                });
            }
        }
    }
</script>

<style scoped></style>

There are a few things happening in the above code. First we’re creating an id variable to be used in our form. This id is populated from the axios request to our API when the component mounts. The id is bound to the form and a method is bound to our button for triggering the second request.

The important pice to note here is the withCredentials property that we are adding to the requests. This allows for our session information to be sent, otherwise the server wouldn’t have a way to distinguish users within incoming requests.

If you try to validate with the data that returns from the first request, you’ll get a success alert. If you change the data in the form and try to validate, it will fail.

Because we are using HTTPS, we cannot use the built in server that comes with Vue.js for testing. We need to be testing with a valid certificate because our backend is expecting it. There are many different ways to accomplish this task, but for simplicity purposes, we’re just going to use an application called Caddy Server. Assuming you have Caddy Server, you can create a Caddyfile at the root of your project:

localhost:2015 {
    root dist
    tls server.cert server.key
}

The above configuration says that we will be serving whatever ends up in the dist directory and we are using HTTPS with our self-signed certificates. These certificate files must be at the root of our project as well. To run our project, we can execute the following:

npm run build
caddy

Again, the above assumes you’re choosing to use Caddy Server. You can choose to use NGINX or Apache httpd, or something else entirely. However, the setup will be different between the applications. The application in our example will be served at https://localhost:2015, which is what we defined in our backend.

If you’d like to learn more about using Caddy Server, check out a previous tutorial I wrote titled, Serve Your Web Applications with Minimal Effort Using Caddy.

Conclusion

You just saw how to manage user sessions in a Node.js and Vue.js application secured with HTTPS and operating on different origins. In short, the focus points of this tutorial were around enabling sessions and allowing cross origin resource sharing (CORS) for them in Node.js, then being able to make requests in a Vue.js application while sending credential information.

As previously mentioned, the purpose was not to demonstrate configuring HTTPS in Node.js because this is something I had already discussed in a previous tutorial. Likewise, I had also demonstrated how to do standard HTTP requests with Vue.js in a previous tutorial as well.

Original article source at: https://www.thepolyglotdeveloper.com/

#javascript #node #vue #https 

How to Manage Sessions Over HTTPS with Node.js and Vue.js
Nat  Grady

Nat Grady

1670417646

How to Install Caddy with PHP & HTTPS using Let’s Encrypt on Ubuntu

Install Caddy with PHP & HTTPS using Let’sEncrypt on Ubuntu. In this guide you are going to learn how to install Caddy with PHP 7.4 and also configure HTTPs on Ubuntu 18.04.

Caddy is a open source web server with automatic HTTPS written in Go language. It takes care of TLS certificate renewals, OCSP stapling, static file serving, reverse proxying, and more.

This tutorial is tested on Google Cloud and AWS, so it works fine on other cloud services like Azure, DigitalOcean or any VPS or any Dedicated servers running Ubuntu.

If you are on Google Cloud you should follow the below listed prerequisites.

Prerequisites for Google Cloud

  1. Your Compute Engine Instance running.
  2. For setting up Compute Engine, see the Setting up Compute Engine Instance.
  3. Set up Cloud DNS, see the Setting up Google Cloud DNS for your domain.

If you are on AWS you should follow these below listed prerequisites.

Prerequisites for AWS

  1. A running EC2 Instance. Learn how to create an AWS EC2 instance.
  2. Assigned a Elastic IP to your EC2 Instance.
  3. Setup and configure Route 53 and point your domain to AWS.
  4. Successful SSH connection to your EC2 Instance.

SSH to your EC2 Instance and perform the steps listed below.

Initial Server Setup

Let’s start by updating the local package index with the following command to the latest available version.

sudo apt update
sudo apt upgrade

Once the update is done you can start the installation of Caddy.

Install Caddy

Once you have your server setup and domain name pointed to your server you can proceed to install Caddy.

Execute the following commands to install Caddy.

curl https://getcaddy.com | sudo bash -s personal

Once the installation is completed you will get an output similar to the one below.

Output
Putting caddy in /usr/local/bin (may require password)
Caddy v1.0.4 (h1:wwuGSkUHo6RZ3oMpeTt7J09WBB87X5o+IZN4dKehcQE=)
Successfully installed

This output shows Caddy is installed in /usr/local/bin.

You can check the version of Caddy installed using this command.

caddy -version

Configure Caddy

Now you need to allow Caddy binary to bind to ports 80 and 443.

Setup directories for Caddy.

sudo mkdir /etc/caddy
sudo mkdir /etc/ssl/caddy 
sudo mkdir /var/log/caddy 

Configure correct permissions.

sudo chown -R root:root /etc/caddy
sudo chown -R root:www-data /etc/ssl/caddy
sudo chown -R root:www-data /var/log/caddy 
sudo chmod 0770 /etc/ssl/caddy

Configure Caddy Systemd service unit

Now you can create a systemd service file for Caddy which is available in the official repository and reload the demon for the changes to be available.

wget https://raw.githubusercontent.com/caddyserver/caddy/master/dist/init/linux-systemd/caddy.service
sudo cp caddy.service /etc/systemd/system/
sudo chown root:root /etc/systemd/system/caddy.service
sudo chmod 644 /etc/systemd/system/caddy.service
sudo systemctl daemon-reload

Install PHP 7.4 FPM

Add the ondrej/php which has PHP 7.4 FPM package and other required PHP extensions.

sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

Install PHP 7.4 and some common extensions.

sudo apt install php7.4-fpm php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl php7.4-bcmath unzip -y

Once PHP 7.4 FPM is installed you can configure your domain name with Caddy.

Configure Domain and Webroot in Caddy

Create a new directory for your website files and configure correct permissions.

sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo nano /var/www/index.html

Create a Caddy file named Caddyfile inside /etc/caddy/ and configure your domain name with HTTPS.

sudo nano /etc/caddy/Caddyfile

Copy the below configuration and paste it inside this file.

https://domain.com {
     root /var/www/

     log /var/log/caddy/domain.log

     tls on
     gzip

     fastcgi / /run/php/php7.4-fpm.sock {
         ext .php
         split .php
         index index.php
     }
}

Hit CTRL + X followed by Y and ENTER to save and exit the file.

Restart/Start Caddy to have the changes available and Let’s Encrypt configured automatically.

sudo service caddy start

If you have your Caddy server started before you can restart using the following command.

sudo service caddy restart

Now you can check the status of Caddy using the following command.

sudo service caddy status

You should see an output similar to the one below.

Output
● caddy.service - Caddy HTTP/2 web server
    Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
    Active: active (running) since Thu 2020-01-30 09:34:54 UTC; 3s ago
      Docs: https://caddyserver.com/docs
  Main PID: 24533 (caddy)
     Tasks: 6 (limit: 661)
    CGroup: /system.slice/caddy.service
            └─24533 /usr/local/bin/caddy -log stdout -log-timestamps=false -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp

If you get any error about Certificate Maintenance or JSON parse, you can try the following steps listed below. If you are fine you can skip it.

sudo rm -rf /etc/ssl/caddy*

Setup Test PHP file

Create a new file to output the installed PHP information.

sudo nano /var/www/index.php

Enter the following code inside it and save the file.

<?php phpinfo();

Verify the Caddy Setup

Once you have restarted Caddy and completed all the setups listed above you can check your domain in your web browser.

You should see the PHP information and your domain loaded with HTTPS.

Prepare yourself for a role working as an Information Technology Professional with Linux operating system

Conclusion

Now you have learned how to install Caddy with PHP 7.4 and also configure HTTPS using Let’s Encrypt on Ubuntu.

Thanks for your time. If you face any problem or any feedback, please leave a comment below.

Original article source at: https://www.cloudbooklet.com/

#php #https #ubuntu 

How to Install Caddy with PHP & HTTPS using Let’s Encrypt on Ubuntu

How to Install Caddy with PHP & HTTPS using Let’s Encrypt on Ubuntu

Install Caddy with PHP & HTTPS using Let’sEncrypt on Ubuntu. In this guide you are going to learn how to install Caddy with PHP 7.4 and also configure HTTPs on Ubuntu 18.04.

Caddy is a open source web server with automatic HTTPS written in Go language. It takes care of TLS certificate renewals, OCSP stapling, static file serving, reverse proxying, and more.

This tutorial is tested on Google Cloud and AWS, so it works fine on other cloud services like Azure, DigitalOcean or any VPS or any Dedicated servers running Ubuntu.

If you are on Google Cloud you should follow the below listed prerequisites.

Prerequisites for Google Cloud

  1. Your Compute Engine Instance running.
  2. For setting up Compute Engine, see the Setting up Compute Engine Instance.
  3. Set up Cloud DNS, see the Setting up Google Cloud DNS for your domain.

If you are on AWS you should follow these below listed prerequisites.

Prerequisites for AWS

  1. A running EC2 Instance. Learn how to create an AWS EC2 instance.
  2. Assigned a Elastic IP to your EC2 Instance.
  3. Setup and configure Route 53 and point your domain to AWS.
  4. Successful SSH connection to your EC2 Instance.

SSH to your EC2 Instance and perform the steps listed below.

Initial Server Setup

Let’s start by updating the local package index with the following command to the latest available version.

sudo apt update
sudo apt upgrade

Once the update is done you can start the installation of Caddy.

Install Caddy

Once you have your server setup and domain name pointed to your server you can proceed to install Caddy.

Execute the following commands to install Caddy.

curl https://getcaddy.com | sudo bash -s personal

Once the installation is completed you will get an output similar to the one below.

Output
Putting caddy in /usr/local/bin (may require password)
Caddy v1.0.4 (h1:wwuGSkUHo6RZ3oMpeTt7J09WBB87X5o+IZN4dKehcQE=)
Successfully installed

This output shows Caddy is installed in /usr/local/bin.

You can check the version of Caddy installed using this command.

caddy -version

Configure Caddy

Now you need to allow Caddy binary to bind to ports 80 and 443.

Setup directories for Caddy.

sudo mkdir /etc/caddy
sudo mkdir /etc/ssl/caddy 
sudo mkdir /var/log/caddy 

Configure correct permissions.

sudo chown -R root:root /etc/caddy
sudo chown -R root:www-data /etc/ssl/caddy
sudo chown -R root:www-data /var/log/caddy 
sudo chmod 0770 /etc/ssl/caddy

Configure Caddy Systemd service unit

Now you can create a systemd service file for Caddy which is available in the official repository and reload the demon for the changes to be available.

wget https://raw.githubusercontent.com/caddyserver/caddy/master/dist/init/linux-systemd/caddy.service
sudo cp caddy.service /etc/systemd/system/
sudo chown root:root /etc/systemd/system/caddy.service
sudo chmod 644 /etc/systemd/system/caddy.service
sudo systemctl daemon-reload

Install PHP 7.4 FPM

Add the ondrej/php which has PHP 7.4 FPM package and other required PHP extensions.

sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

Install PHP 7.4 and some common extensions.

sudo apt install php7.4-fpm php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl php7.4-bcmath unzip -y

Once PHP 7.4 FPM is installed you can configure your domain name with Caddy.

Configure Domain and Webroot in Caddy

Create a new directory for your website files and configure correct permissions.

sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo nano /var/www/index.html

Create a Caddy file named Caddyfile inside /etc/caddy/ and configure your domain name with HTTPS.

sudo nano /etc/caddy/Caddyfile

Copy the below configuration and paste it inside this file.

https://domain.com {
     root /var/www/

     log /var/log/caddy/domain.log

     tls on
     gzip

     fastcgi / /run/php/php7.4-fpm.sock {
         ext .php
         split .php
         index index.php
     }
}

Hit CTRL + X followed by Y and ENTER to save and exit the file.

Restart/Start Caddy to have the changes available and Let’s Encrypt configured automatically.

sudo service caddy start

If you have your Caddy server started before you can restart using the following command.

sudo service caddy restart

Now you can check the status of Caddy using the following command.

sudo service caddy status

You should see an output similar to the one below.

Output
● caddy.service - Caddy HTTP/2 web server
    Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
    Active: active (running) since Thu 2020-01-30 09:34:54 UTC; 3s ago
      Docs: https://caddyserver.com/docs
  Main PID: 24533 (caddy)
     Tasks: 6 (limit: 661)
    CGroup: /system.slice/caddy.service
            └─24533 /usr/local/bin/caddy -log stdout -log-timestamps=false -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp

If you get any error about Certificate Maintenance or JSON parse, you can try the following steps listed below. If you are fine you can skip it.

sudo rm -rf /etc/ssl/caddy*

Setup Test PHP file

Create a new file to output the installed PHP information.

sudo nano /var/www/index.php

Enter the following code inside it and save the file.

<?php phpinfo();

Verify the Caddy Setup

Once you have restarted Caddy and completed all the setups listed above you can check your domain in your web browser.

You should see the PHP information and your domain loaded with HTTPS.

Prepare yourself for a role working as an Information Technology Professional with Linux operating system

Conclusion

Now you have learned how to install Caddy with PHP 7.4 and also configure HTTPS using Let’s Encrypt on Ubuntu.

Thanks for your time. If you face any problem or any feedback, please leave a comment below.

Original article source at: https://www.cloudbooklet.com/

#php #https #ubuntu 

How to Install Caddy with PHP & HTTPS using Let’s Encrypt on Ubuntu
Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

precil james86

1667393659

Buy German #Zertifikat in Germany,#language Zertifikat Without #Exam i

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

Buy German #Zertifikat in Germany,#language Zertifikat Without #Exam i

precil james86

1667393523

buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

buy testdaf   #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy

precil james86

1667393459

#(onlinedocuments100@outlook.com)Buy #German Registered Telc #Deutsche

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

#(onlinedocuments100@outlook.com)Buy #German Registered Telc #Deutsche

precil james86

1667393288

#(onlinedocuments100@outlook.com)Get Goethe-Zertifikat A1, Buy #Goethe

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

#(onlinedocuments100@outlook.com)Get Goethe-Zertifikat A1, Buy #Goethe

precil james86

1667391737

(onlinedocuments100@outlook.com)VALID /TELC/TEFL/GOETHE A1 A2 B1 B2 C1

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

(onlinedocuments100@outlook.com)VALID /TELC/TEFL/GOETHE A1 A2 B1 B2 C1

precil james86

1667390622

Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy val

#(+1 773 922-0936)Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich, Frankfurt, Hamburg, Cologne,Buy original TELC-TESTDAF-Goethe-Zertifikat C1 in Nuremberg, Dresden, Shuttgart, Leipzig, Dusseldorf, Bonn, Heidelberg,Buy legit Goethe-Zertifikat B2, buy registered Goethe-TELC-Zertifikat B1 for sale online without exams, 
Get Goethe-Zertifikat A1, Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy valid buy testdaf Zertifikat B2, Buy DSH certificate, Buy dtz certificate,buy testdaf Zertifikat online in Bremen, Hanover, Essen, Aachen, Regenshurg, Lubeck, Dortmund, Trier, 
Freiburg Im Breisgau,buy testas certificate Berlin,  Ösd certificate, DAF German certificate, German language test, german language test for visa,buy #german a1 exams in #Mainz, #Augsburg, #Duisburg, #Wiesbaden, #Potsdam, #Mannheim, #Bamberg, #Bielefeld, german a2 #exam,buy german a2 exam #papers with #answers, german a2 lesen practice #test, b2 german test #sample. ( onlinedocuments100@outlook.com)

Buy original IELTS-CAE-DELE-SIELE-PTE-NEBOSH-TESTDAF-TESTAS-Goethe-IOSH-CILS-PLIDA-DALF-DILF certificates online for sale without exams in #Erfurt, #Wuppertal, #Koblenz, #Bochum, #Munster, #Kiel, #Kassel, #Chemnitz, #Wurzburg, #Osnabruck, #Krefeld, #Magdeburg, #Rostock,#Brunswick, #Gorlitz, #Saarbrucken #https://www.buylanguagecertificates.com #Weimar, #Bremerhaven, #Erlangen, #Halle, #Jena, #Rothenburg, #Buy #IELTS certificate, Buy #CELPIP Certificate, Buy OET #Certificate, Buy #Goethe c#ertificate, Buy #PTE Certificate, Buy #NEBOSH certifcate, Buy #DALF Certificate, Buy #IOSH certificate, Buy #HSE Certificate, Buy Buy #NEBOSH HSW, Buy Fake #Degrees, Buy Fake #Diploma, Buy CAE certificate, Buy TELC certificates,Buy IELTS certificate without exam  Buy DELE certificate, Buy SIELE Certificate, Buy CEFR Certificate,Buy CEDILS Certificate, Buy PLida Certificate, Buy DITALS Certificate online, Buy Original AIL LET Certificate, Buy CILS certificate, Buy CELI certificate,Buy DELF Certificate without exams, Buy #DALF certificate for sale, Purchase DILF Certificate Online, Buy TCF certificate, Buy Valid CNaVT certificate, hr certification canada,Buy TOEIC certificate, Buy CHST Certificate, Buy TEXES certificate, Buy IT certification, Buy HSK certificate, Buy CEH Certificate, Buy DPLT Certificate, Buy CST Certificate,Buy CRCST Certificate, Buy TESTDAF certificate, Buy #TESTAS certificate.Buy Goethe A1 ,B2 ,C1 certificate online without writing exam in Portugal,Germany, Italy, France, India. DSH Goethe TesDAF Telc A1, A2, B1, B2, C1, C2 Certificate((WhatsApp:+1 773 922-0936)) Buy registered verified TELC-GOETHE Zertifikat C1 in Berlin, Munich.

Goethe-Zertifikat A1: Fit in Deutsch 1
Goethe-Zertifikat A1: Start Deutsch 1
Goethe-Zertifikat A2: Fit in
Deutsch
Goethe-Zertifikat A2
Goethe-Zertifikat B1
Goethe-Zertifikat B2
Goethe-Zertifikat C1
Goethe-Zertifikat C2:

Buy #DSH certificate without exams, Buy DTZ certificate for sale, Buy #TEFL certificate, Buy CAT certificate, Buy CTET Certificate, Buy BAR certification, Buy CCC Certification, Buy CE Certificate, Buy ISO Certificate, Buy TEF Certificate, AP Certificate, Buy GRE Certificate, Buy samtrac certificate without exam, #Goethe-Zertifikat B2,buy original Goethe-Zertifikat B2 for sale online without exams, Goethe-Zertifikat B1, buy testdaf #Zertifikat B1, testdaf Zertifikat, buy testas certificate,  Ösd certificate,DAF #German certificate, b1 german test, #b2 german test, buy B1, B2 German certificate for sale, goethe zertifikat b2 2022, Buy HSKK certificate without exam, Goethe-Zertifikat C1, buy-testdaf-goethe-dsh-certificates, buy-original-nebosh-igc-diploma-certificate-in-uk, Buy Goethe-TELC-TESTDAF-Zertifikat B1,C1 online, buy #testdaf-gothe-telc certificates for sale online without exam in Spain, Mongolia, USA ielts.We operate 24/7 Contact Details :: :( onlinedocuments100@outlook.com)
www.buylanguagecertificates.com/
General support #(verifiedielts770@yahoo.com)
WhatsApp:: (+1 773 922-0936)

Buy #Goethe-Zertifikat A2 for sale buy testdaf #Zertifikat B1, Buy val

Creating A CRUD Desktop Application Using Python eel and Sqlite3

Subscribe: https://www.youtube.com/c/Cairocoders/featured 

Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.

https://github.com/ChrisKnott/Eel 

Install

pip install eel

C:\python_dev\crud>pip install eel

Install PyAutoGUI

https://pypi.org/project/PyAutoGUI/

pip install PyAutoGUI

C:\python_dev\crud>pip install PyAutoGUI

Create Database sqlite3 using python

//createdb.py
import sqlite3
from sqlite3 import Error 
   
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
   
   
if __name__ == '__main__':
    create_connection(r"C:\python_dev\crud\views\database\storage.db")

run
C:\python_dev\crud>python createdb.py

Create Database Table

CREATE TABLE tblemployee (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR (150),
position VARCHAR (150),
office VARCHAR (150)

);

#main.py
import eel
from views.models.employee import showallrecords, save_newemployee, show_selectedEmployee, update_newemployee, show_deleteEmployee
import pyautogui #https://pypi.org/project/PyAutoGUI/
  
eel.init('views')
   
@eel.expose
def fetchalldata():
    select_reg = showallrecords()
    eel.action_out(select_reg)
  
@eel.expose 
def btn_save(name, position, office):
    msg = save_newemployee(name, position, office)
    eel.save_return(str(msg))
 
@eel.expose
def get_employee(id):
    select_employee = show_selectedEmployee(id)
    eel.action_edit(select_employee)
     
@eel.expose 
def btn_update(name, position, office, id):
    msg = update_newemployee(name, position, office, id)
    eel.update_return(str(msg))    
 
@eel.expose
def get_delete_employee(id):
    select_del_employee = show_deleteEmployee(id)
    eel.delete_return(select_del_employee)
     
eel.start(
    'templates/index.html',
    size=pyautogui.size()
)
#employee.py
import sqlite3
  
def showallrecords():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee")
        registers = []
        for item in cursor.fetchall():
            #test = item[1]
            #print(test)
            registers.append(item)
        return registers
    except Exception as error:
        print(error)
        msg = "Error"
        return msg
         
def save_newemployee(name, position, office):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
 
        if name != "" and position != "" and office != "":
            cursor.execute("INSERT INTO tblemployee(name, position, office) VALUES(?,?,?)",(name, position, office))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
  
def show_selectedEmployee(id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee WHERE id =?", (id,))
        editemployees = []
        for item in cursor.fetchone():
            editemployees.append(item)
        return editemployees
 
    except Exception as error:
        print(error)
        msg = "Error"
        return msg
 
def update_newemployee(name, position, office, id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
 
        if name != "" and position != "" and office != "":
            cursor.execute("UPDATE tblemployee SET name =?, position =?, office =? WHERE id =?",
                             (name, position, office, id,))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
         
def show_deleteEmployee(id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("DELETE FROM tblemployee WHERE id =?", (id,))
        connect.commit()
        connect.close()
        msg = "success"
        return msg
             
    except Exception as error:
        print(error)
        msg = "Error"
        return msg

Make your Front-end HTML CSS and Javascript
crud\views\templates\index.html

//crud\views\templates\index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="../css/index.css">
    <link rel="icon" href="../img/myglogo.png">
    <title>Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel</title>
</head>
<body>
<div class="container">
<p style="text-align:center;"><h2>Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel</h2></p>
<p style="text-align:right;"><button type="button" class="btn" id="btn_addnew">Add New</button></p>
<table id="employeedatatable" class="styled-table">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Action</th>
    </tr>
</table> 
 
<div class="modalContainer" id="Addnewmodal">
  <div class="modal-content">
    <span id="close" class="close">×</span>
    <p style="text-align:center;"><h2>Add New Employee</h2></p>
    <form class="form-detail" action="#" method="post" id="myform">
        <div class="form-row">
            <label>Full Name:</label> 
            <input type="text" name="txtfullname" id="txtfullname" class="input-text" required placeholder="ex: Cairocoders Ednalan">
        </div>
        <div class="form-row">
            <label>Position:</label>
            <input type="text" name="txtposition" id="txtposition" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Office:</label>
            <input type="text" name="txtoffice" id="txtoffice" class="input-text" required>
        </div>
        <div class="form-row-last">
            <input type="submit" name="register" class="button" value="Add New Employee" onclick="save_register_js();">
        </div>
        <div class="box"><label class="label_input" id="return_register" style="width: 90%;color:green;font-weight:bold;"></label></div>
    </form>
  </div>
</div>
 
<div class="modalContainer" id="Edit_modal">
  <div class="modal-content">
    <span id="close" class="closeedit">×</span>
    <p style="text-align:center;"><h2>Edit Employee</h2></p>
    <form class="form-detail" action="#" method="post" id="myformedit"><input type="hidden" name="id" id="id">
        <div class="form-row">
            <label>Full Name:</label> 
            <input type="text" name="edit_name" id="edit_name" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Position:</label>
            <input type="text" name="edit_position" id="edit_position" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Office:</label>
            <input type="text" name="edit_office" id="edit_office" class="input-text" required>
        </div>
        <div class="form-row-last">
            <input type="submit" name="register" class="button" value="Update" onclick="save_edit();">
        </div>
        <div class="box"><label class="label_input" id="return_update" style="width: 90%;color:green;font-weight:bold;"></label></div>
    </form>
  </div>
</div>
 
<div class="modalContainer" id="Delete_modal">
  <div class="modal-content">
    <span id="close" class="closedelete">×</span>
    <p style="text-align:center;"><h2>Delete Employee</h2></p>
    <p style="text-align:center;"><h3>Are you sure you want to delete this data?</h3></p>
    <div class="form-detail">
    <input type="hidden" name="idvalue" id="idvalue"> 
    <input type="submit" name="btndelete" class="button" value="Delete" onclick="btn_submitdelete($('#idvalue').val());">
    <div class="box"><label class="label_input" id="return_delete" style="width: 90%;color:green;font-weight:bold;"></label></div>
    </div>
  </div>
</div>
 
</div>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.validate.min.js"></script>
<script type="text/javascript" src="../js/main.js"></script>
</body>
</html>

crud\views\js\main.js

#crud\views\js\main.js
$(document).ready(function(){
    eel.fetchalldata()
     
  $("#btn_addnew").on("click", function() {
    $("#Addnewmodal").show();
  });
  $(".close").on("click", function() {
    $("#Addnewmodal").hide();
  });
   
  $(".closeedit").on("click", function() {
    $("#Edit_modal").hide();
  });  
  $(".closedelete").on("click", function() {
    $("#Delete_modal").hide();
  });
})
   
function link(target) {
    window.location.href=target;
}
 
eel.expose(action_out)
function action_out(registers){ 
    //alert("Show Table");
    registers.forEach(showdata)
}
 
eel.expose(action_edit)
function action_edit(editemployees){ 
   //alert(editemployees);
   editemployees.forEach(get_array_values)
}
 
function get_array_values(item, index){
    //alert(item);
    //alert(index);
    if (index == 0) {
        document.getElementById("id").value = item;
    } else if (index == 1) {
        document.getElementById("edit_name").value = item;
    } else if (index == 2) {
        document.getElementById("edit_position").value = item;
    } else if (index == 3) {
        document.getElementById("edit_office").value = item;
    }
    else {}
 
}
// SAVE 
async function save_edit(){
    $( "#myformedit" ).validate({
        messages: {
            edit_name: {
                required: "Please provide Name"
            },
            edit_position: {
                required: "Please provide Position"
            },
            edit_office: {
                required: "Please provide Office"
            },
        },
        submitHandler: function(form) {
            eel.btn_update($('#edit_name').val(),$('#edit_position').val(),$('#edit_office').val(),$('#id').val())
            //alert("Success");
        }
    });
}
         
function showdata(item, index){
    var get_table = document.getElementById("employeedatatable");
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    var td2 = document.createElement("td");
    var td3 = document.createElement("td");
    var td4 = document.createElement("td");
    var td5 = document.createElement("td");
     
    var id = item[0]
    td.innerText = item[0]
    td2.innerText = item[1]
    td3.innerText = item[2]
    td4.innerText = item[3]
         
    td5.innerHTML = '<button type="button" class="btn" onclick="btn_edit('+ id +')">Edit</button> | <button type="button" class="btndelete" onclick="buttondelete(('+ id +'))">Delete</button>'
         
    get_table.appendChild(tr)
    tr.appendChild(td)
    tr.appendChild(td2)
    tr.appendChild(td3)
    tr.appendChild(td4)
    tr.appendChild(td5)
}
     
// NEW Employee
async function save_register_js(){
    $( "#myform" ).validate({
            messages: {
                txtfullname: {
                    required: "Please provide Name"
                },
                txtposition: {
                    required: "Please provide Position"
                },
                txtoffice: {
                    required: "Please provide Office"
                },
            },
            submitHandler: function(form) {
                eel.btn_save($('#txtfullname').val(),$('#txtposition').val(),$('#txtoffice').val())
            }
    });
};
     
eel.expose(save_return); 
function save_return(status){
    if (status == "success"){
        $('#return_register').text('New Employee completed successfully!');
        $('#txtfullname').val('');
        $('#txtposition').val('');
        $('#txtoffice').val('');
    }
    if (status == "failure"){
        $('#return_register').text('Error when registering, make sure you have no blank fields.');
    }
};
     
eel.expose(edit_return); 
function edit_return(status){
    if (status == "success"){
        $('#return_register').text('Employee Updated successfully!');
    }
    if (status == "failure"){
        $('#return_register').text('Error when updating, make sure you have no blank fields.');
    }
};
   
function buttondelete(id)
{
    document.getElementById("idvalue").value = id;
    $("#Delete_modal").show();
}
 
async function btn_edit(id){ 
    eel.get_employee(id)
    $("#Edit_modal").show();
}
 
async function btn_submitdelete(id){ 
    //alert(id);
    eel.get_delete_employee(id)
}
 
eel.expose(update_return); 
function update_return(status){
    if (status == "success"){
        $('#return_update').text('Employee Updated successfully!');
        $('#txtfullname').val('');
        $('#txtposition').val('');
        $('#txtoffice').val('');
    }
    if (status == "failure"){
        $('#return_update').text('Error when updating record, make sure you have no blank fields.');
    }
};
 
eel.expose(delete_return)
function delete_return(delemployees){ 
   alert(delemployees);
    if (status == "success"){
        location.href = "index.html";
    }
    if (status == "failure"){
        $('#return_delete').text('Error deleting record');
    }
}

crud\views\css\index.css

//crud\views\css\index.css
body {
    color: #162D5D;
    font-family: 'Roboto', sans-serif;
}
.container {margin:30px;}
.styled-table {
    border-collapse: collapse;width:100%;
    margin: 25px 0;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.styled-table thead tr {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.styled-table th,
.styled-table td {
    padding: 12px 15px;
}
.styled-table tr {
    border-bottom: 1px solid #dddddd;
}
.styled-table tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.styled-table tr:last-of-type {
    border-bottom: 2px solid #009879;
}
.btn {
    background-color: #04AA6D!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.btndelete {
    background-color: #cf2e2e!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.form-detail .form-row label.error {
    color: red;
}
.form-detail .input-text {
    margin-bottom: 27px;
}
.form-detail input {
    width: 91%;
    padding: 14.5px 15px;
    border: 1px solid #e5e5e5;
    border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    appearance: unset;
    -moz-appearance: unset;
    -webkit-appearance: unset;
    -o-appearance: unset;
    -ms-appearance: unset;
    outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    font-family: 'Roboto', sans-serif;
    font-size: 16px;
    color: #333;
}
.form-detail .form-row input:focus {
    border: 1px solid #53c83c;
}
.form-detail .button {
    background: #3b63ca;
    border-radius: 6px;
    -o-border-radius: 6px;
    -ms-border-radius: 6px;
    -moz-border-radius: 6px;
    -webkit-border-radius: 6px;
    width: 160px;
    border: none;
    margin: 6px 0 50px 0px;
    cursor: pointer;
    font-family: 'Roboto', sans-serif;
    color: #fff;
    font-weight: 500;
    font-size: 16px;
}
.form-detail .button:hover {
    background: #3356b0;
}
.modalContainer {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
  background-color: #fefefe;
  margin: 15% auto;
  padding: 20px;
  border: 1px solid #888;
  width: 40%;
}
 
#close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
}

Jquery
https://jquery.com/download/
CDN : jsDelivr CDN
https://www.jsdelivr.com/package/npm/jquery
https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js

jQuery Validation
http://jqueryvalidation.org/

Run : C:\python_dev\crud>python main.py

#python 

Creating A CRUD Desktop Application Using Python eel and Sqlite3

Fetch All Records Sqlite3 using Python Eel | Python Desktop App

Python Desktop App Fetch All Records sqlite3 using python eel

In today's tutorial we will build a Python Desktop Application Fetch all sqlite3 records using python eel

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.

python eel : https://morioh.com/p/d9714cb91304

Subscribe: https://www.youtube.com/c/Cairocoders/featured  

Source Code

Install

pip install eel

C:\python_dev\table>pip install eel

Install PyAutoGUI

https://pypi.org/project/PyAutoGUI/

pip install PyAutoGUI

C:\python_dev\table>pip install PyAutoGUI

Create Database sqlite3 using python

#createdb.py
import sqlite3
from sqlite3 import Error 
  
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
  
  
if __name__ == '__main__':
    create_connection(r"C:\python_dev\table\views\database\storage.db")

run
C:\python_dev\table>python createdb.py

#main.py
import eel
from views.models.fetchdata import showallrecords
import pyautogui #https://pypi.org/project/PyAutoGUI/
 
eel.init('views')
  
@eel.expose
def get_registers():
    select_reg = showallrecords()
    eel.action_out(select_reg)
     
eel.start(
    'index.html',
    size=pyautogui.size()
)

Create Table
 

CREATE TABLE tblemployee (

id INTEGER PRIMARY KEY AUTOINCREMENT,

name VARCHAR (150),

position VARCHAR (150),

office VARCHAR (150)

);

#table\views\models\fetchdata.py
import sqlite3
 
def showallrecords():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee")
        registers = []
        for item in cursor.fetchall():
            #test = item[1]
            #print(test)
            registers.append(item)
        return registers
    except Exception as error:
        print(error)
        msg = "Error"
        return msg

Make your Front-end HTML CSS and Javascript
 

//table\views\index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="css/index.css">
    <link rel="icon" href="img/myglogo.png">
    <title>Python Registration</title>
</head>
<body>
<div class="container">
<p style="text-align:center;"><h2>Python Desktop App Fetch All Records sqlite3 using python eel</h2></p>
<p style="text-align:right;"><button type="button" class="btn">Add New</button></p>
<table id="employeedatatable" class="styled-table">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Action</th>
    </tr>
</table> 
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
    $(document).ready(function(){
        eel.get_registers()
    })
         
    eel.expose(action_out)
    function action_out(registers){ 
        //alert("Show Table");
        registers.forEach(showdata)
    }
         
    function showdata(item, index){
        var get_table = document.getElementById("employeedatatable");
        var tr = document.createElement("tr");
        var td = document.createElement("td");
        var td2 = document.createElement("td");
        var td3 = document.createElement("td");
        var td4 = document.createElement("td");
        var td5 = document.createElement("td");
 
        td.innerText = item[0]
        td2.innerText = item[1]
        td3.innerText = item[2]
        td4.innerText = item[3]
                 
        td5.innerHTML = '<button type="button" class="btn" onclick="buttonedit()">Edit</button> | <button type="button" class="btndelete" onclick="buttondelete()">Delete</button>'
        //td5.className = "acoes"
        //td5.setAttribute("onclick","actions(this, 'documents');")
                 
        get_table.appendChild(tr)
        tr.appendChild(td)
        tr.appendChild(td2)
        tr.appendChild(td3)
        tr.appendChild(td4)
        tr.appendChild(td5)
    }
    function buttonedit()
    {
      alert("Edit Records")
    }   
    function buttondelete()
    {
        if(confirm("Are you sure you want to delete this?")) {
            alert("Successfully Deleted");
        }else{
            return false;
        }
    }
 
</script>
</body>
</html>
//table\views\css\index.css
.container {margin:30px;}
.styled-table {
    border-collapse: collapse;width:100%;
    margin: 25px 0;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.styled-table thead tr {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.styled-table th,
.styled-table td {
    padding: 12px 15px;
}
.styled-table tr {
    border-bottom: 1px solid #dddddd;
}
.styled-table tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.styled-table tr:last-of-type {
    border-bottom: 2px solid #009879;
}
.btn {
    background-color: #04AA6D!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.btndelete {
    background-color: #cf2e2e!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}

#python 

Fetch All Records Sqlite3 using Python Eel | Python Desktop App
Lawrence  Lesch

Lawrence Lesch

1662433080

Hotel: A Simple Process Manager for Developers

hotel

Start apps from your browser and use local domains/https automatically

Tip: if you don't enable local domains, hotel can still be used as a catalog of local servers.

Hotel works great on any OS (macOS, Linux, Windows) and with all servers ❤️

  • Node (Express, Webpack)
  • PHP (Laravel, Symfony)
  • Ruby (Rails, Sinatra, Jekyll)
  • Python (Django)
  • Docker
  • Go
  • Apache, Nginx
  • ...

To all the amazing people who have answered the Hotel survey, thanks so much <3 !

v0.8.0 upgrade

.localhost replaces .dev local domain and is the new default. See https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/ for context.

If you're upgrading, please be sure to:

  1. Remove "tld": "dev" from your ~/.hotel/conf.json file
  2. Run hotel stop && hotel start
  3. Refresh your network settings

Support

If you are benefiting from hotel, you can support its development on Patreon.

You can view the list of Supporters here https://thanks.typicode.com.

Video

Features

  • Local domains - http://project.localhost
  • HTTPS via local self-signed SSL certificate - https://project.localhost
  • Wildcard subdomains - http://*.project.localhost
  • Works everywhere - macOS, Linux and Windows
  • Works with any server - Node, Ruby, PHP, ...
  • Proxy - Map local domains to remote servers
  • System-friendly - No messing with port 80, /etc/hosts, sudo or additional software
  • Fallback URL - http://localhost:2000/project
  • Servers are only started when you access them
  • Plays nice with other servers (Apache, Nginx, ...)
  • Random or fixed ports

Install

npm install -g hotel && hotel start

Hotel requires Node to be installed, if you don't have it, you can simply install it using one of the following method:

You can also visit https://nodejs.org.

Quick start

Local domains (optional)

To use local .localhost domains, you need to configure your network or browser to use hotel's proxy auto-config file or you can skip this step for the moment and go directly to http://localhost:2000

See instructions here.

Add your servers

# Add your server to hotel
~/projects/one$ hotel add 'npm start'
# Or start your server in the terminal as usual and get a temporary local domain
~/projects/two$ hotel run 'npm start' 

Visit localhost:2000 or http(s)://hotel.localhost.

Alternatively you can directly go to

http://localhost:2000/one
http://localhost:2000/two
http(s)://one.localhost
http(s)://two.localhost 

Popular servers examples

Using other servers? Here are some examples to get you started :)

hotel add 'ember server'                               # Ember
hotel add 'jekyll serve --port $PORT'                  # Jekyll
hotel add 'rails server -p $PORT -b 127.0.0.1'         # Rails
hotel add 'python -m SimpleHTTPServer $PORT'           # static file server (Python)
hotel add 'php -S 127.0.0.1:$PORT'                     # PHP
hotel add 'docker-compose up'                          # docker-compose
hotel add 'python manage.py runserver 127.0.0.1:$PORT' # Django
# ...

On Windows use "%PORT%" instead of '$PORT'

See a Docker example here..

Proxy requests to remote servers

Add your remote servers

~$ hotel add http://192.168.1.12:1337 --name aliased-address
~$ hotel add http://google.com --name aliased-domain 

You can now access them using

http://aliased-address.localhost # will proxy requests to http://192.168.1.12:1337
http://aliased-domain.localhost # will proxy requests to http://google.com

CLI usage and options

hotel add <cmd|url> [opts]
hotel run <cmd> [opts]

# Examples

hotel add 'nodemon app.js' --out dev.log  # Set output file (default: none)
hotel add 'nodemon app.js' --name name    # Set custom name (default: current dir name)
hotel add 'nodemon app.js' --port 3000    # Set a fixed port (default: random port)
hotel add 'nodemon app.js' --env PATH     # Store PATH environment variable in server config
hotel add http://192.168.1.10 --name app  # map local domain to URL

hotel run 'nodemon app.js'                # Run server and get a temporary local domain

# Other commands

hotel ls     # List servers
hotel rm     # Remove server
hotel start  # Start hotel daemon
hotel stop   # Stop hotel daemon

To get help

hotel --help
hotel --help <cmd>

Port

For hotel to work, your servers need to listen on the PORT environment variable. Here are some examples showing how you can do it from your code or the command-line:

var port = process.env.PORT || 3000
server.listen(port)
hotel add 'cmd -p $PORT'  # OS X, Linux
hotel add "cmd -p %PORT%" # Windows

Fallback URL

If you're offline or can't configure your browser to use .localhost domains, you can always access your local servers by going to localhost:2000.

Configurations, logs and self-signed SSL certificate

You can find hotel related files in ~/.hotel :

~/.hotel/conf.json
~/.hotel/daemon.log
~/.hotel/daemon.pid
~/.hotel/key.pem
~/.hotel/cert.pem
~/.hotel/servers/<app-name>.json

By default, hotel uses the following configuration values:

{
  "port": 2000,
  "host": '127.0.0.1',
  
  // Timeout when proxying requests to local domains
  "timeout": 5000,
  
  // Change this if you want to use another tld than .localhost
  "tld": 'localhost', 
  
  // If you're behind a corporate proxy, replace this with your network proxy IP (example: "1.2.3.4:5000")
  "proxy": false
}

To override a value, simply add it to ~/.hotel/conf.json and run hotel stop && hotel start

Third-party tools

FAQ

Setting a fixed port

hotel add --port 3000 'server-cmd $PORT' 

Adding X-Forwarded-* headers to requests

hotel add --xfwd 'server-cmd'

Setting HTTP_PROXY env

Use --http-proxy-env flag when adding your server or edit your server configuration in ~/.hotel/servers

hotel add --http-proxy-env 'server-cmd'

Proxying requests to a remote https server

hotel add --change-origin 'https://jsonplaceholder.typicode.com'

When proxying to a https server, you may get an error because your .localhost domain doesn't match the host defined in the server certificate. With this flag, host header is changed to match the target URL.

ENOSPC and EACCES errors

If you're seeing one of these errors in ~/.hotel/daemon.log, this usually means that there's some permissions issues. hotel daemon should be started without sudo and ~/.hotel should belong to $USER.

# to fix permissions
sudo chown -R $USER: $HOME/.hotel

See also, https://docs.npmjs.com/getting-started/fixing-npm-permissions

Configuring a network proxy IP

If you're behind a corporate proxy, replace "proxy" with your network proxy IP in ~/.hotel/conf.json. For example:

{
  "proxy": "1.2.3.4:5000"
}

Download Details:

Author: Typicode
Source Code: https://github.com/typicode/hotel 
License: MIT license

#javascript #front #local #https #proxy 

Hotel: A Simple Process Manager for Developers

Echo: High Performance, Minimalist Go Web Framework

Supported Go versions

As of version 4.0.0, Echo is available as a Go module. Therefore a Go version capable of understanding /vN suffixed imports is required:

  • 1.9.7+
  • 1.10.3+
  • 1.14+

Any of these versions will allow you to import Echo as github.com/labstack/echo/v4 which is the recommended way of using Echo going forward.

For older versions, please use the latest v3 tag.

Feature Overview

  • Optimized HTTP router which smartly prioritize routes
  • Build robust and scalable RESTful APIs
  • Group APIs
  • Extensible middleware framework
  • Define middleware at root, group or route level
  • Data binding for JSON, XML and form payload
  • Handy functions to send variety of HTTP responses
  • Centralized HTTP error handling
  • Template rendering with any template engine
  • Define your format for the logger
  • Highly customizable
  • Automatic TLS via Let’s Encrypt
  • HTTP/2 support

Benchmarks

Date: 2020/11/11
Source: https://github.com/vishr/web-framework-benchmark
Lower is better!

The benchmarks above were run on an Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz

Guide

Installation

// go get github.com/labstack/echo/{version}
go get github.com/labstack/echo/v4

Example

package main

import (
  "github.com/labstack/echo/v4"
  "github.com/labstack/echo/v4/middleware"
  "net/http"
)

func main() {
  // Echo instance
  e := echo.New()

  // Middleware
  e.Use(middleware.Logger())
  e.Use(middleware.Recover())

  // Routes
  e.GET("/", hello)

  // Start server
  e.Logger.Fatal(e.Start(":1323"))
}

// Handler
func hello(c echo.Context) error {
  return c.String(http.StatusOK, "Hello, World!")
}

Third-party middlewares

RepositoryDescription
github.com/labstack/echo-contrib(by Echo team) casbin, gorilla/sessions, jaegertracing, prometheus, pprof, zipkin middlewares
deepmap/oapi-codegenAutomatically generate RESTful API documentation with OpenAPI Client and Server Code Generator
github.com/swaggo/echo-swaggerAutomatically generate RESTful API documentation with Swagger 2.0.
github.com/ziflex/lechoZerolog logging library wrapper for Echo logger interface.
github.com/brpaz/echozapUber´s Zap logging library wrapper for Echo logger interface.
github.com/darkweak/souin/plugins/echoHTTP cache system based on Souin to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs.
github.com/mikestefanello/pagodaRapid, easy full-stack web development starter kit built with Echo.

Please send a PR to add your own library here.

Help

Contribute

Use issues for everything

  • For a small change, just send a PR.
  • For bigger changes open an issue for discussion before sending a PR.
  • PR should have:
    • Test case
    • Documentation
    • Example (If it makes sense)
  • You can also contribute by:
    • Reporting issues
    • Suggesting new features or enhancements
    • Improve/fix documentation

Credits

Author: Labstack
Source Code: https://github.com/labstack/echo 
License: MIT license

#go #golang #web #https 

Echo: High Performance, Minimalist Go Web Framework
津田  直子

津田 直子

1653509940

6分で HTTPとHTTPSの違いについてわかりやすく解説!

本動画では、よく聞くHTTPとHTTPSの違いをわかりやすくお伝えします!
知っているようで実はよく知らなかった用語の代表格とも言えるこの2つの違いをしっかり抑えておくことは、インターネットを普段使用するみなさんにとって非常に重要です!
6分でサクッと簡単に理解できる内容となっておりますので、是非楽しんでお聞きいただければと思います!

#http  #https 

6分で HTTPとHTTPSの違いについてわかりやすく解説!