When you create a new user account in your Google Cloud MySQL database, it has the same privileges as a root user. It is, therefore, a good idea to limit the admin privileges of the new MySQL user with the REVOKE command and explicitly grant the required user privileges with the GRANT statement.
You can use MySQL Workbench or Sequel Pro to connect to your Cloud SQL database with the root user. Make sure that your database has a public IP and your computer’s IP address is added as an authorized network in the Connections tab of your Database console.
SHOW GRANTS FOR db_user
If your MySQL user has root privileges, the statement will output the following:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'db_user'@'%' WITH GRANT OPTION
As a first step, you can revoke all privileges from the user account. You can either specify individual permissions, separated by commas, but since the root user has many privileges, we can revoke them all and grant the required one in another statement.
REVOKE ALL PRIVILEGES, GRANT OPTION FROM db_user
Next, we tell the server to reload the privileges from the grant tables in the MySQL system schema.
FLUSH PRIVILEGES
Finally, grant the required privileges to the user. In our case, the user should only be able to read, insert, view and delete rows from all tables in a specific database.
GRANT SELECT, UPDATE, INSERT, DELETE ON db_name.* TO db_user
Execute the Flush Privileges statement again to apply the changes.
FLUSH PRIVILEGES
You may also run the SHOW GRANTS statement to verify that the correct privileges have been applied to the user.
Whether you are a new Mac user or a seasoned veteran looking to do even more amazing things on your Mac, check out this updated collection of lesser-known but awesome Mac Apps of 2020. The majority of apps listed here are free and they’ll appeal to general Mac users, not just the techie crowd.
The Best Mac Apps & Utilities
This collection of essential Mac Apps includes mostly lesser-known apps so the popular ones — like Evernote, Dropbox, Skype, OneNote, or Google Drive — aren’t listed here. Also, all the apps here are compatible with Yosemite and Catalina, the current version of Mac OS.
Wherever possible, I have included the Mac App Store links because the store not only makes it easy for you to install apps on your Mac but, in the case of paid apps, you also have an option for requesting refunds.
Let’s get started.
Magnet - A perfect windows management app for Mac that lets you move and resize windows with configurable keyboard shortcuts. You can move windows between multiple displays too. Another alternative is Rectangle.
ImageOptim - Always run your images through ImageOptim before uploading them on to your website. The Mac app will crush the size of your image files without affecting the visual quality.
HiddenMe - If your Mac desktop is cluttered with folders and files, you can hide all the icons with a single click or with a keyboard shortcut.
Site Sucker - Download entire websites includes images, PDF files and mirror them on your local disk for offline browsing. Like wget but with a visual interface.
App Cleaner - The best uninstaller for your Mac that will automatically remove all the extra files that are left on the disk when you delete an app.
Maccy - A clipboard manager that stores all that you copy to the clipboard and lets you paste the copied snippets into other apps with a simple shortcut. [CopyClip] is a good alternative.
Clean Me - Recover space on your Mac by deleting all the system logs, cache and other temp files that your Mac can easily do away with.
Dozer - An excellent alternative to the popular Bartender app. You can quickly re-order or even hide the app icons appearing in the Mac menu bar.
NetNewsWire - A clean and fast RSS Reader for your MacOS. We have an RSS Feed too!
RSS Bot - Access your RSS from your Mac’s menu bar and get notifications when new items are available. You can also apply filters to only show articles that match certain keywords.
Flotato - It turns any web page into a native Mac app that you can quickly open outside the web browser. Also see, Fluid.
Latest - It scans the Applications folder of your Mac and checks if all your installed apps are up to date. You can also update your outdated apps. MacUpdater is an even more powerful but paid alternative.
Onyx - Perform system maintenance tasks to improve the performance of your Mac, verify disks and more.
TinkerTool - It provides access to several configuration settings that are otherwise hidden on the Mac. For instance, you can specify the default folder where Screenshots should be saved on the Mac.
KeepingYouAwake - It keeps your Mac stay awake and also prevents your screen from going to sleep. If you need more features, use Amphetamine.
Shifty - Easily toggle between dark and light mode on your Mac. You can also decide which of your Apps or websites should stay light, while your system runs in Dark Mode. Also see, NightOwl.
IINA - A modern alternative to the VLC Media Player that includes support for gestures and the touch bar in newer Macs.
HyperSwitch - An improved window switching app for Mac that upgrades your default Command + Tab experience when cycling between open app windows.
TextBar - You can specify system commands and the app will add the text output of those commands to the menu bar. For instance, ipconfig getifaddr en0 will print your current IP address. You can also have these as desktop widgets with Übersicht.
Tyke - A minimalistic notepad app that sits in the menu bar and lets you save quick notes.
Karabiner - Remap existing keys on the keyboard to perform a different command. For instance, the CAPS lock key can be configured to work as an Escape key. Useful when using any non-Apple keyboard with Mac.
Dropzone - It makes it easy to copy or move files to your favorite folders, open applications and you can also upload files to the Internet right from your menu bar.
Clocker - Show multiple clocks in your menu bar from different timezones.
Duet Display - Use your iPad, iPhone or even an Android phone as an extra display for your Mac and PC.
Transmit - The perfect FTP client for Mac OS X that just works. You can create droplets to instantly upload files to your favorite destinations from anywhere.
AirDroid - It connects your Android phone to the Mac. You can access messages, manage photos, transfer files and more, wirelessly.
Unarchiver - It’s like WinZip compression utility for Mac that can handle all the popular archive formats including RAR, TAR, GZIP, ISO, and more.
Handbrake - Convert video files from one format to another. FFmpeg is powerful too but works only from the command line. For audio files, the recommended converter is fre:ac.
Disk Inventory - If the Macbook is running low on space, use the Disk Inventory app to quickly discover large files and folders that are clogging the storage.
Helium - An Always on Top like app but for your Mac. The browser window will float on top of other windows and you can also change the translucency level.
XMenu - It provides explorer-style access to your favorite folders and Mac apps from the menu bar. You can launch apps, browse files and folders right from the menu bar.
Flux - It automatically dims the brightness of your screen based on the time of the day - warm at night, bright during the day - so your eyes feel less strain. Also see the 20 20 20 rule.
Text Expander - The app accelerates your touch typing by replacing pre-defined abbreviations with corresponding phrases. For instance, say ;sig to add your rich signature in the Gmail window.
CheatSheet - Use this app to memorize keyboard shortcuts for any Mac app. Just hold the Command Key a bit longer to get a list of all shortcuts available in that app.
Soundflower - If you are to record the Mac audio, like the sound coming out of the speakers, you would need SoundFlower to route that sound to the recording app instead of the speakers.
JumpShare - Quickly upload files, record screencasts, capture screenshots and share them instantly, all from the convenience of your menu bar.
Hocus Focus - It helps keep your Mac desktop clean by automatically hiding windows that are inactive or haven’t been used for a while. You can even choose to hide windows as soon as they lose focus.
Bandwidth+ - Monitor your Internet bandwidth usage in realtime. Especially handy when you are connected to a metered Wi-Fi hotspot.
Background Music - An audio utility that provides per-application volume control for your Mac. It automatically pauses your music player when a second audio source is playing and unpauses the player when the second source has stopped.
Download Shuttle - A fast download manager for Mac that will split the files into multiple chunks and downloads them in parallel. Can pause and resume downloads too.
WeTransfer- Send big files to anyone by simply drag and drop. You get a download link that automatically becomes inactive after 7 days.
LICEcap - A light-weight screencast app for capturing any area of your Mac desktop as a small GIF file. Also see, Kap.
Hazel - A folder monitoring app that lets you specify rules per watched folder and any files added to these folders are automatically organized. Supports AppleScript and Automator actions too.
Authy - Not exactly a Mac app but a Chrome App that you cannot do without. It lets you log into online accounts that have 2-factor authentication enabled without requiring the phone.
Self Control - To help you stop procrastinating, this Mac app that can temporarily block access to time-wasting websites, emails and everything else that you find distracting.
Better Touch Tool - The app lets you modify the gestures of your Magic Mouse and the Magic Trackpad. You can configure Touch Bar settings and actions too.
OBS - If you ever plan to set up a live stream on Twitch or YouTube, OBS is the only streaming software you’d need.
Zoom - My favorite app for video conferencing on Mac. You can do screen sharing, the meetings are automatically recorded and you can remotely control the attendee’s computer for tech support.
To Do - A perfect todo and task management app for your Mac from Microsoft. Also see, Trello.
Reddit offers a fairly extensive API that any developer can use to easily pull data from subreddits. You can fetch posts, user comments, image thumbnails, votes and most other attributes that are attached to a post on Reddit.
The only downside with the Reddit API is that it will not provide any historical data and your requests are capped to the 1000 most recent posts published on a subreddit. So, for instance, if your project requires you to scrape all mentions of your brand ever made on Reddit, the official API will be of little help.
You have tools like wget that can quickly download entire websites for offline use but they are mostly useless for scraping Reddit data since the site doesn’t use page numbers and content of pages is constantly changing. A post can be listed on the first page of a subreddit but it could be pushed to the third page the next second as other posts are voted to the top.
Download Reddit Data with Google Scripts
While there exist quite a Node.js and Python libraries for scraping Reddit, they are too complicated to implement for the non-techie crowd. Fortunately, there’s always Google Apps Script to the rescue.
Here’s Google script that will help you download all the user posts from any subreddit on Reddit to a Google Sheet. And because we are using pushshift.io instead of the official Reddit API, we are no longer capped to the first 1000 posts. It will download everything that’s every posted on a subreddit.
To get started, open the Google Sheet and make a copy in your Google Drive.
Go to Tools -> Script editor to open the Google Script that will fetch all the data from the specified subreddit. Go to line 55 and change technology to the name of the subreddit that you wish to scrape.
While you are in the script editor, choose Run -> scrapeReddit.
Authorize the script and within a minute or two, all the Reddit posts will be added to your Google Sheet.
Technical Details - How to the Script Works
The first step is to ensure that the script not hitting any rate limits of the PushShift service.
Next, we specify the subreddit name and run our script to fetch posts in batches of 1000 each. Once a batch is complete, we write the data to a Google Sheet.
const getAPIEndpoint_ =(subreddit, before ='')=>{const fields =['title','created_utc','url','thumbnail','full_link'];const size =1000;const base ='https://api.pushshift.io/reddit/search/submission';const params ={ subreddit, size, fields: fields.join(',')};if(before) params.before = before;const query = Object.keys(params).map(key=>`${key}=${params[key]}`).join('&');return`${base}?${query}`;};const scrapeReddit =(subreddit ='technology')=>{let before ='';do{const apiUrl =getAPIEndpoint_(subreddit, before);const response = UrlFetchApp.fetch(apiUrl);const{ data }=JSON.parse(response);const{ length }= data;
before = length >0?String(data[length -1].created_utc):'';if(length >0){writeDataToSheets_(data);}}while(before !==''&&!isRateLimited());};
The default response from Push Shift service contains a lot of fields, we are thus using the fields parameter to only request the relevant data like post title, post link, date created and so on.
If the response contains a thumbnail image, we convert that into a Google Sheets function so you can preview the image inside the sheet itself. The same is done for URLs.
Bonus Tip: Every search page and subreddit on Reddit can be converted into JSON format using a simple URL hack. Just append .json to the Reddit URL and you have a JSON response.
For instance, if the URL is https://www.reddit.com/r/todayIlearned, the same page can be accessed in JSON format using the URL https://www.reddit.com/r/todayIlearned.json.
This works for search results as well. The search page for https://www.reddit.com/search/?q=india can be downloaded as JSON using https://www.reddit.com/search.json?q=india.
Some email messages you have sent through your Gmail account may not get delivered at all. There could be a problem with the recipient’s email address, like a typo, their mailbox could be full or maybe the mail server could be specifically blocking your emails due to the content of the message.
When an email message sent via Gmail is bounced or rejected, you get an automated bounce-back notice from mailer-daemon@gmail.com and it will always contain the exact reason for the delivery failure along with the SMTP error code. For instance, an error code 550 indicates that the email address doesn’t exist while a 554 indicates that your email was classified as spam by the recipient’s mail server.
How to Get a List of Email Addresses that Bounced
It is important to keep track of your bounced messages and remove all undelivered email addresses from your future mailings as they may affect your sending reputation.
Mail Merge for Gmail keeps track of all your bounced messages in Gmail but if you are not using mail merge yet, here’s an open-source Google Script that will prepare a list of all email addresses that have bounced inside a Google Spreadsheet.
Gmail Bounce Report - Getting Started
Here’s how you can get started:
Click here to make a copy of the Google Spreadsheet.
Open the Bounced Emails menu in your Google Sheet and then select the Run Report option.
Authorize the Google Script so it can scan your Gmail account for bounced emails and write them to the Google Sheet. The script runs entirely in your Google account, no data is stored or shared anywhere.
Watch as the Google Sheet is populated with rejected and bounced email addresses.
The email bounce report includes the email address that bounced, the reason why that email failed to deliver and the date when the bounce occurred. The spreadsheet will also have a direct link to the bounced message received from mailer-daemon.
Technical Details - How the Script Works
The script uses the Gmail API to fetch a list of all bounced emails in your mailbox.
constfindBouncedEmails=()=>{const{ messages =[]}= Gmail.Users.Messages.list('me',{
q:'from:mailer-daemon',
maxResults:200});for(let m =0; m < messages.length; m +=1){const bounceData =parseGmailMessage(messages[m].id);if(bounceData){
SpreadsheetApp.getActiveSheet().appendRow(bounceData);}}};
Next, the script parses the headers of bounced email messages with regex and writes the bounced information to the Google Sheet.
constparseGmailMessage=messageId=>{const message = GmailApp.getMessageById(messageId);const body = message.getPlainBody();const[, failAction]= body.match(/^Action:\s*(.+)/m)||[];/* If failAction is "delayed", igore message since Gmail will retry it */if(failAction ==='failed'){/* The X-Failed-Recipients header in Gmail contains the recipient's address */const emailAddress = message.getHeader('X-Failed-Recipients');/* Get the SMTP error code
The first sub-field indicates whether the delivery attempt was successful
(2= success, 4 = persistent temporary failure, 5 = permanent failure). */const[, errorStatus]= body.match(/^Status:\s*([.\d]+)/m)||[];/* The Diagnostic-Code DSN field contains the actual diagnostic code
Some mail systems supply no additional information beyond that
which is returned in the 'action' and 'status' fields. */const[,, bounceReason]=
body.match(/^Diagnostic-Code:\s*(.+)\s*;\s*(.+)/m)||[];return[
message.getDate(),
emailAddress,
errorStatus,
bounceReason.replace(/\s*(Please|Learn|See).+$/,''),`=HYPERLINK("${message.getThread().getPermalink()}";"View")`];}returnfalse;};
Inside your Google Sheet, go to the Tools menu and choose Script Editor to view the full source code of the Google Script. You are welcome to reuse / modify the code.
You can use Google Apps Script to automatically reset the password of users in your GSuite domain. This script can only be executed under the Suite admin account. You also need to enable the AdminDirectory Advanced Service in your Apps Script Editor.
You can force reset passwords of members of a particular group in your organization or specify a list of email addresses and the Google Script will use the AdminDirectory service to change the password of specified users.
constgetGroupMembers_=groupEmail=>{var emails =[];var pageToken;do{const{ members =[], nextPageToken }= AdminDirectory.Members.list(
groupEmail,{
maxResults:200,
pageToken: pageToken
});
members.forEach(member=>{if(member.status ==="ACTIVE"){
emails.push(member.email);}});
pageToken = nextPageToken;}while(pageToken);return emails;};constsendEmail_=(emailAddress, password)=>{
MailApp.sendEmail({
to: emailAddress,
cc:"amit@labnol.org",
subject:`Password changed for ${emailAddress}`,
body:`The GSuite admin has changed your Gmail password to ${password}`});};constchangePassword_=emailAddress=>{const temporaryPassword = Utilities.getUuid();
AdminDirectory.Users.update({
password: temporaryPassword,
changePasswordAtNextLogin:true},
emailAddress
);sendEmail_(emailAddress, temporaryPassword);};constresetUserPasswordsForGroup=()=>{const groupEmail = “groupemail@labnol.org”;const members =getGroupMembers_(groupEmail);
members.forEach(member=>changePassword_(member));};constresetGSuitePasswordForUsers=()=>{const members =["user1@example.com","user2@example.com","user3@example.com"];
members.forEach(member=>changePassword_(member));};
Change GSuite Passwords Periodically
You can create a time-based trigger in Google Scripts to automatically run the reset function at specific intervals (like update password on the first of every month).
The Google Script is written in ES6 with V8 runtime. If V8 is not enabled for your GSuite account, replace the manifest appsscript.json file with this:
This step-by-step tutorial will show you how to install Let’s Encrypt SSL certificate for an Apache server running on Ubuntu 18.04. I’ve created a droplet on DigitalOcean for this example but the steps should be similar AWS and other environments.
Install Apache 2
Login to your droplet with root (or use sudo with all the following commands).
Check if any Ubuntu packages are outdated.
apt update
Upgrade the outdated packages to the latest version.
Install the certbot DNS plugin for DigitalOcean. This will automatically add the _acme-challenge TXT DNS records to your domain that are required for authentication. The records are also removed after the certificates are installed.
This will only work if you are using the DigitalOcean Name Servers with your domain.
Create DigitalOcean Credentials File
Go to your DigitalOcean account’s dashboard, choose API and choose “Generate New Token”. Copy the token to your clipboard. Inside the terminal, create a new directory ~/.ssh and create a new file to save the credentials.
vi ~/.ssh/digitalocean.ini
Paste the following line in the credentials file. Replace 1234 with your actual token value.
dns_digitalocean_token = 1234
Save the file and then run chmod to restrict access to the file.
chmod 600 ~/.ssh/digitalocean.ini
Install SSL Certificates
Replace labnol.org with your domain name. This command will install the wildcard SSL certificate for all subdomains and the main domain.
If the certificate is successfully installed, it will add the certificate and chain in the following directory
/etc/letsencrypt/live/labnol.org/
Test the SSL Certificate
Go to ssllabs.com to test if your new SSL certificate is correctly installed on your domain.
Configure Apache to Use SSL Certificate
Now that the SSL Certificate is installed, we need to enable SSL for the Apache server on Ubuntu.
Enable the SSL module for Apache
OpenSSL is installed with Ubuntu but it is disabled by default. Enable the SSL module and restart Apache to apply the changes.
sudo a2enmod ssl
sudo service apache2 restart
Update Apache Configuration File
Open the default virtual host configuration file /etc/apache2/sites-enabled/000-default.confand paste the following lines. Replace labnol with your own domain name.
Save the file and restart Apache. The SSLCertificateFile and SSLCertificateKeyFile files were saved by certbot in the /etc/letsencrypt/live directory.
Adjust the Firewall
In some cases, you may have to enable Apache on SSL port 443 manually with the following command.
sudo ufw allow "Apache Secure"
Restart Apache. All your HTTP traffic will automatically redirect to the HTTPS version with a 301 permanent redirect.
sudo service apache2 restart
Verify Auto Renewal Process
Your Let’s Encrypt SSL certificate will auto-expire every 90 days. Go to the /etc/cron.d/ folder and you should see a certbot file. This cron job will automatically renew your SSL certificate if the expiration is within 30 days.
You can also run the following command to verify if the renewal process is correctly setup.
How do you embed a PDF document into your website for inline viewing? One popular option is that you upload the PDF file to an online storage service, something like Google Drive or Microsoft’s OneDrive, make the file public and then copy-paste the IFRAME code provided by these services to quickly embed the document in any website.
Here’s a sample PDF embed code for Google Drive that works across all browsers.
This is the most common method for embedding PDFs - it is simple, it just works but the downside is that you have no control over how the PDF files are presented in your web pages.
If you prefer to offer a more customized and immersive reading experience for PDFs in your website, check out the new Adobe View SDK. This is part of the Adobe Document Cloud platform but doesn’t cost a penny.
Here are some unique features that make this PDF embed solution stand out:
You can add annotation tools inside the PDF viewer. Anyone can annotate the embedded PDF and download the modified file.
If you have embedded a lengthy document with multiple pages, readers can use the thumbnail view to quickly jump to any page.
The PDF viewer can be customized to hide options for downloading and printing PDF files.
There’s built-in analytics so you know how many people saw your PDF file and how they interacted with the document.
And my favorite feature of ViewSDK is the inline embed mode. Let me explain that in detail.
Display PDF Pages Inline like Images and Videos
In Inline Mode, and this is unique to Adobe View SDK, all pages of the embedded PDF document are displayed at once so your site visitors do not have to scroll another document with the parent web page. The PDF controls are hidden from the user and the PDF pages blend with images and other HTML content on your web page.
To learn more, check this live demo - here the PDF document contains 7 pages but all are displayed at once like one long web page thus offering smooth navigation.
How to Embed PDFs with the Adobe View SDK
It does take a few extra steps to use the View SDK. Go to adobe.io and create a new set of credentials for your website. Please note that credentials are valid for one domain only so if you have multiple websites, you’d need a different set of credentials for them.
Next, open the playground and generate the embed code. You need to replace the clientId with your set of credentials. The url in the sample code should point to the location of your PDF file.