Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Go Standard Library Cookbook
Go Standard Library Cookbook

Go Standard Library Cookbook: Over 120 specific ways to make full use of the standard library components in Golang

eBook
€22.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Go Standard Library Cookbook

Interacting with the Environment

In this chapter, the following recipes are covered:

  • Retrieving the Golang version
  • Accessing program arguments
  • Creating a program interface with the flag package
  • Getting and setting environment variables with default values
  • Retrieving the current working directory
  • Getting the current process PID
  • Handling operating system signals
  • Calling an external process
  • Retrieving child process information
  • Reading/writing from the child process
  • Shutting down the application gracefully
  • File configuration with functional options

Introduction

Every program, once it is executed, exists in the environment of the operating system. The program receives input and provides output to this environment. The operating system also needs to communicate with the program to let it know what's happening outside. And finally, the program needs to respond with appropriate actions.

This chapter will walk you through the basics of the discovery of the system environment, the program parameterization via program arguments, and the concept of the operating system signals. You will also learn how to execute and communicate with the child process.

Retrieving the Golang version

While building a program, it is a good practice to log the environment settings, build version, and runtime version, especially if your application is more complex. This helps you to analyze the problem, in case something goes wrong.

Besides the build version and, for example, the environmental variables, the Go version by which the binary was compiled could be included in the log. The following recipe will show you how to include the Go runtime version into such program information.

Getting ready

Install and verify the Go installation. The following steps could help:

  1. Download and install Go on your machine.
  2. Verify that your GOPATH and GOROOT environmental variables are set properly.
  3. Open your Terminal and execute go version. If you get output with a version name, then Go is installed properly.
  4. Create a repository in the GOPATH/src folder.

How to do it...

The following steps cover the solution:

  1. Open the console and create the folder chapter01/recipe01.
  2. Navigate to the directory.
  3. Create the main.go file with the following content:
        package main
import (
"log"
"runtime"
)
const info = `
Application %s starting.
The binary was build by GO: %s`

func main() {
log.Printf(info, "Example", runtime.Version())
}

  1. Run the code by executing the go run main.go.
  2. See the output in the Terminal:

How it works...

The runtime package contains a lot of useful functions. To find out the Go runtime version, the Version function could be used. The documentation states that the function returns the hash of the commit, and the date or tag at the time of the binary build.

The Version function, in fact, returns the runtime/internal/sys .The Version constant. The constant itself is located in the $GOROOT/src/runtime/internal/sys/zversion.go file.

This .go file is generated by the go dist tool and the version is resolved by the findgoversion function in the go/src/cmd/dist/build.go file, as explained next.

The $GOROOT/VERSION takes priority. If the file is empty or does not exist, the $GOROOT/VERSION.cache file is used. If the $GOROOT/VERSION.cache is also not found, the tool tries to resolve the version by using the Git information, but in this case, you need to initialize the Git repository for the Go source.

Accessing program arguments

The most simple way to parameterize the program run is to use the command-line arguments as program parameters.

Simply, the parameterized program call could look like this: ./parsecsv user.csv role.csv. In this case, parsecsv is the name of the executed binary and user.csv and role.csv are the arguments, that modify the program call (in this case it refers to files to be parsed).

How to do it...

  1. Open the console and create the folder chapter01/recipe02.
  2. Navigate to the directory.
  3. Create the main.go file with the following content:
        package main
import (
"fmt"
"os"
)

func main() {

args := os.Args

// This call will print
// all command line arguments.
fmt.Println(args)

// The first argument, zero item from slice,
// is the name of the called binary.
programName := args[0]
fmt.Printf("The binary name is: %s \n", programName)

// The rest of the arguments could be obtained
// by omitting the first argument.
otherArgs := args[1:]
fmt.Println(otherArgs)

for idx, arg := range otherArgs {
fmt.Printf("Arg %d = %s \n", idx, arg) }
}
  1. Build the binary by executing go build -o test.
  2. Execute the command ./test arg1 arg2. (Windows users can run test.exe arg1 arg2).
  3. See the output in the Terminal:

How it works...

The Go standard library offers a few ways to access the arguments of the program call. The most generic way is to access the arguments by the Args variable from the OS package.

This way you can get all the arguments from the command line in a string slice. The advantage of this approach is that the number of arguments is dynamic and this way you can, for example, pass the names of the files to be processed by the program.

The preceding example just echoes all the arguments that are passed to the program. Finally, let's say the binary is called test and the program run is executed by the Terminal command ./test arg1 arg2.

In detail, the os.Args[0] will return ./test. The os.Args[1:] returns the rest of the arguments without the binary name. In the real world, it is better to not rely on the number of arguments passed to the program, but always check the length of the argument array. Otherwise, naturally, if the argument on a given index is not within the range, the program panics.

There's more...

If the arguments are defined as flags, -flag value, additional logic is needed to assign the value to the flag. In this case, there is a better way to parse these by using the flag package. This approach is part of the next recipe.

Creating a program interface with the flag package

The previous recipe describes how to access the program arguments by a very generic approach.

This recipe will provide a way of defining an interface via the program flags. This approach dominates systems based on GNU/Linux, BSD, and macOS. The example of the program call could be ls -l which will, on *NIX systems, list the files in a current directory.

The Go package for flag handling does not support flag combining like ls -ll, where there are multiple flags after a single dash. Each flag must be separate. The Go flag package also does not differentiate between long options and short ones. Finally, -flag and --flag are equivalent.

How to do it...

  1. Open the console and create the folder chapter01/recipe03.
  2. Navigate to the directory.
  3. Create the main.go file with the following content:
        package main
import (
"flag"
"fmt"
"log"
"os"
"strings"
)

// Custom type need to implement
// flag.Value interface to be able to
// use it in flag.Var function.
type ArrayValue []string

func (s *ArrayValue) String() string {
return fmt.Sprintf("%v", *s)
}

func (a *ArrayValue) Set(s string) error {
*a = strings.Split(s, ",")
return nil
}

func main() {

// Extracting flag values with methods returning pointers
retry := flag.Int("retry", -1, "Defines max retry count")

// Read the flag using the XXXVar function.
// In this case the variable must be defined
// prior to the flag.
var logPrefix string
flag.StringVar(&logPrefix, "prefix", "", "Logger prefix")

var arr ArrayValue
flag.Var(&arr, "array", "Input array to iterate through.")

// Execute the flag.Parse function, to
// read the flags to defined variables.
// Without this call the flag
// variables remain empty.
flag.Parse()

// Sample logic not related to flags
logger := log.New(os.Stdout, logPrefix, log.Ldate)

retryCount := 0
for retryCount < *retry {
logger.Println("Retrying connection")
logger.Printf("Sending array %v\n", arr)
retryCount++
}
}
  1. Build the binary by executing the go build -o util.
  2. From the console, execute ./util -retry 2 -prefix=example -array=1,2.
  1. See the output in the Terminal:

How it works...

For the flag definition in code, the flag package defines two types of functions.

The first type is the simple name of the flag type such as Int. This function will return the pointer to the integer variable where the value of the parsed flag is.

The XXXVar functions are the second type. These provide the same functionality, but you need to provide the pointer to the variable. The parsed flag value will be stored in the given variable.

The Go library also supports a custom flag type. The custom type must implement the Value interface from the flag package.

As an example, let's say the flag retry defines the retry limit for reconnecting to the endpoint, the prefix flag defines the prefix of each row in a log, and the array is the array flag that will be send as an payload to server. The program call from the Terminal will look like ./util -retry 2 -prefix=example array=1,2.

The important part of the preceding code is the Parse() function which parses the defined flags from Args[1:]. The function must be called after all flags are defined and before the values are accessed.

The preceding code shows how to parse some data types from the command-line flags. Analogously, the other built-in types are parsed.

The last flag, array, demonstrates the definition of the custom type flag. Note that the ArrayType implements the Value interface from the flag package.

There's more...

The flag package contains more functions to design the interface with flags. It is worth reading the documentation for FlagSet.

By defining the new FlagSet, the arguments could be parsed by calling the myFlagset.Parse(os.Args[2:]). This way you can have flag subsets based on, for example, the first flag.

Getting and setting environment variables with default values

The previous recipe, Creating a program interface with the flag package, describes how to use flags as program parameters.

The other typical way of parameterization, especially for larger applications, is the configuration with the use of environment variables. Environment variables as a configuration option significantly simplify the deployment of the applications. These are also very common in cloud infrastructure.

Usually, the configuration of a database connection for a local and for an automated build environment is different.

If the configuration is defined by the environment variables, it is not necessary to change the application config files or even the application code. The exported environment variables (for example, DBSTRING) are all we need. It is also very practical to default the configuration if the environmental variable is not in place. This way, the life of the application developers is much easier.

This recipe will demonstrate how to read, set and unset the environment variable. It will also show you how to implement the default option if the variable is not set.

How to do it...

  1. Open the console and create the folder chapter01/recipe04.
  2. Navigate to the directory.
  1. Create the get.go file with the following content:
        package main

import (
"log"
"os"
)

func main() {
connStr := os.Getenv("DB_CONN")
log.Printf("Connection string: %s\n", connStr)
}
  1. Execute the code by calling DB_CONN=db:/user@example && go run get.go in the Terminal.
  2. See the output in the Terminal:
  1. Create the lookup.go file with the following content:
        package main

import (
"log"
"os"
)

func main() {

key := "DB_CONN"

connStr, ex := os.LookupEnv(key)
if !ex {
log.Printf("The env variable %s is not set.\n", key)
}
fmt.Println(connStr)
}
  1. Execute the code by calling unset DB_CONN && go run lookup.go in the Terminal.
  2. See the output in the Terminal:
  1. Create the main.go file with the following content:
        package main
import (
"log"
"os"
)

func main() {

key := "DB_CONN"
// Set the environmental variable.
os.Setenv(key, "postgres://as:as@example.com/pg?
sslmode=verify-full")
val := GetEnvDefault(key, "postgres://as:as@localhost/pg?
sslmode=verify-full")
log.Println("The value is :" + val)

os.Unsetenv(key)
val = GetEnvDefault(key, "postgres://as:as@127.0.0.1/pg?
sslmode=verify-full")
log.Println("The default value is :" + val)

}

func GetEnvDefault(key, defVal string) string {
val, ex := os.LookupEnv(key)
if !ex {
return defVal
}
return val
}
  1. Run the code by executing go run main.go.
  2. See the output in the Terminal:

How it works...

The environment variables are accessed by the Getenv and Setenv functions in the os package. The names of the functions are self-explanatory and do not need any further description.

There is one more useful function in the os package. The LookupEnv function provides two values as a result; the value of the variable, and the boolean value which defines if the variable was set or not in the environment.

The disadvantage of the os.Getenv function is that it returns an empty string, even in cases where the environment variable is not set.

This handicap could be overcome by the os.LookupEnv function, which returns the string as a value of the environment variable and the boolean value that indicates whether the variable was set or not.

To implement the retrieval of the environment variable or the default one, use the os.LookupEnv function. Simply, if the variable is not set, which means that the second returned value is false, then the default value is returned. The use of the function is part of step 9.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Develop high quality, fast and portable applications by leveraging the power of Go Standard Library.
  • Practical recipes that will help you work with the standard library algorithms to boost your productivity as a Go developer.
  • Compose your own algorithms without forfeiting the simplicity and elegance of the Standard Library.

Description

Google's Golang will be the next talk of the town, with amazing features and a powerful library. This book will gear you up for using golang by taking you through recipes that will teach you how to leverage the standard library to implement a particular solution. This will enable Go developers to take advantage of using a rock-solid standard library instead of third-party frameworks. The book begins by exploring the functionalities available for interaction between the environment and the operating system. We will explore common string operations, date/time manipulations, and numerical problems. We'll then move on to working with the database, accessing the filesystem, and performing I/O operations. From a networking perspective, we will touch on client and server-side solutions. The basics of concurrency are also covered, before we wrap up with a few tips and tricks. By the end of the book, you will have a good overview of the features of the Golang standard library and what you can achieve with them. Ultimately, you will be proficient in implementing solutions with powerful standard libraries.

Who is this book for?

This book is for Go developers who would like to explore the power of Golang and learn how to use the Go standard library for various functionalities. The book assumes basic Go programming knowledge.

What you will learn

  • Access environmental variables
  • Execute and work with child processes
  • Manipulate strings by performing operations such as search, concatenate, and so on
  • Parse and format the output of date/time information
  • Operate on complex numbers and effective conversions between different number formats and bases
  • Work with standard input and output
  • Handle filesystem operations and file permissions
  • Create TCP and HTTP servers, and access those servers with a client
  • Utilize synchronization primitives
  • Test your code
Estimated delivery fee Deliver to Latvia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Feb 27, 2018
Length: 340 pages
Edition : 1st
Language : English
ISBN-13 : 9781788475273
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Latvia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Feb 27, 2018
Length: 340 pages
Edition : 1st
Language : English
ISBN-13 : 9781788475273
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 107.97
Security with Go
€32.99
Distributed Computing with Go
€32.99
Go Standard Library Cookbook
€41.99
Total 107.97 Stars icon

Table of Contents

12 Chapters
Interacting with the Environment Chevron down icon Chevron up icon
Strings and Things Chevron down icon Chevron up icon
Dealing with Numbers Chevron down icon Chevron up icon
Once Upon a Time Chevron down icon Chevron up icon
In and Out Chevron down icon Chevron up icon
Discovering the Filesystem Chevron down icon Chevron up icon
Connecting the Network Chevron down icon Chevron up icon
Working with Databases Chevron down icon Chevron up icon
Come to the Server Side Chevron down icon Chevron up icon
Fun with Concurrency Chevron down icon Chevron up icon
Tips and Tricks Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
(1 Ratings)
5 star 0%
4 star 0%
3 star 0%
2 star 0%
1 star 100%
Leam Hall Oct 15, 2018
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
Really didn't get fully past the first chapter. The author has an engaging style and if Packt had done a decent job editing and fixing this could be a classic. When contacted they wanted me to spend time logging all their problems for free. Since there were more than a dozen in Chapter 1 I figured it wasn't worth the time.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela