public static function execute( $params ) {
		// Set Gdrive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		$backup_folder = $gdrive->listFolder( ai1wm_archive_folder() );

		if ( isset( $backup_folder['items'] ) && ( $item = array_shift( $backup_folder['items'] ) ) ) {
			$backup_folder = $item;
		} else {
			return $params;
		}

		$files = $gdrive->listFolder( null, $backup_folder['id'], array(
			'orderBy' => 'createdDate',
		) );

		$backups = array();
		foreach ( $files['items'] as $backup ) {
			if ( $backup['kind'] === 'drive#file' ) {
				$backups[] = $backup;
			}
		}

		// Skip calculations if there are no backups to delete
		if ( count( $backups ) === 0 ) {
			return $params;
		}

		// Number of backups
		if ( ( $backups_limit = get_option( 'ai1wmge_gdrive_backups', 0 ) ) ) {
			if ( ( $backups_to_remove = count( $backups ) - $backups_limit ) > 0 ) {
				for ( $index = 0; $index < $backups_to_remove; $index++ ) {
					$gdrive->delete( $backups[$index]['id'] );
				}
			}
		}

		// Sort backups by date desc
		$backups = array_reverse( $backups );

		// Get the size of the latest backup before we remove it
		$size_of_backups = $backups[0]['fileSize'];

		// Remove the latest backup, the user should have at least one backup
		array_shift( $backups );

		if ( ( $retention_size = ai1wm_parse_size( get_option( 'ai1wmge_gdrive_total', 0 ) ) ) ) {
			foreach ( $backups as $backup ) {
				$size_of_backups += $backup['fileSize'];
				if ( $size_of_backups > $retention_size ) {
					$gdrive->delete( $backup['id'] );
				}
			}
		}

		return $params;
	}
	public static function execute( $params ) {

		// Set progress
		Ai1wm_Status::info( __( 'Connecting to Google Drive...', AI1WMGE_PLUGIN_NAME ) );

		// Open achive file
		$archive = new Ai1wm_Compressor( ai1wm_archive_path( $params ) );

		// Append EOF block
		$archive->close( true );

		// Set Gdrive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		// Get or Create folder
		$folder = $gdrive->listFolder( ai1wm_archive_folder() );
		if ( isset( $folder['items'] ) && ( $item = array_shift( $folder['items'] ) ) ) {
			$folder = $item;
		} else {
			$folder = $gdrive->createFolder( ai1wm_archive_folder() );
		}

		// Upload resumable
		$params['uploadUrl'] = $gdrive->uploadResumable(
			ai1wm_archive_name( $params ),
			ai1wm_archive_bytes( $params ),
			$folder['id']
		);

		return $params;
	}
	public function account() {
		// Set Gdrive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		// Get account info
		$account = $gdrive->getAccountInfo();

		// Set account name
		$name = null;
		if ( isset( $account['name'] ) ) {
			$name = $account['name'];
		}

		// Set used quota
		$used = null;
		if ( isset( $account['quotaBytesUsed'] ) ) {
			$used = $account['quotaBytesUsed'];
		}

		// Set total quota
		$total = null;
		if ( isset( $account['quotaBytesTotal'] ) ) {
			$total = $account['quotaBytesTotal'];
		}

		return array(
			'name'     => $name,
			'used'     => size_format( $used ),
			'total'    => size_format( $total ),
			'progress' => ceil( ( $used / $total ) * 100 ),
		);
	}
	public static function folder() {
		// Set folder ID
		$folderId = null;
		if ( isset( $_GET['folderId'] ) ) {
			$folderId = $_GET['folderId'];
		}

		// Set Gdrive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		// List folder
		$folder = $gdrive->listFolder( null, $folderId );

		// Set folder structure
		$response = array( 'id' => null, 'items' => array() );

		// Set folder ID
		if ( isset( $folder['id'] ) ) {
			$response['id'] = $folder['id'];
		}

		// Set folder items
		if ( isset( $folder['items'] ) && ( $items = $folder['items'] ) ) {
			foreach ( $items as $item ) {
				$response['items'][] = array(
					'id'    => isset( $item['id'] ) ? $item['id'] : null,
					'name'  => isset( $item['title'] ) ? $item['title'] : null,
					'mime'  => isset( $item['mimeType'] ) ? $item['mimeType'] : null,
					'size'  => isset( $item['fileSize'] ) ? size_format( $item['fileSize'] ) : null,
					'bytes' => isset( $item['fileSize'] ) ? $item['fileSize'] : null,
					'ext'   => isset( $item['fileExtension'] ) ? $item['fileExtension'] : null,
				);
			}
		}

		echo json_encode( $response );
		exit;
	}
	public static function execute( $params ) {

		$completed = false;

		// File ID
		if ( ! isset( $params['fileId'] ) ) {
			throw new Ai1wm_Import_Exception(
				__( 'Google Drive File ID is not specified. ', AI1WMGE_PLUGIN_NAME )
			);
		}

		// Set startBytes
		if ( ! isset( $params['startBytes'] ) ) {
			$params['startBytes'] = 0;
		}

		// Set endBytes
		if ( ! isset( $params['endBytes'] ) ) {
			$params['endBytes'] = ServMaskGdriveClient::CHUNK_SIZE;
		}

		// Set retry
		if ( ! isset( $params['retry'] ) ) {
			$params['retry'] = 0;
		}

		// Set Google Drive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		// Get archive file
		$archive = fopen( ai1wm_archive_path( $params ), 'ab' );

		try {
			// Increase number of retries
			$params['retry'] += 1;

			// Download file chunk
			$gdrive->getFile( $params['fileId'], $archive, $params );
		} catch ( Exception $e ) {
			// Retry 3 times
			if ( $params['retry'] <= 3 ) {
				return $params;
			}

			throw $e;
		}

		// Reset retry counter
		$params['retry'] = 0;

		// Close the archive file
		fclose( $archive );

		// Calculate percent
		$percent = (int) ( ( $params['startBytes'] / $params['totalBytes'] ) * 100 );

		// Set progress
		Ai1wm_Status::progress( $percent );

		// Next file chunk
		if ( empty( $params['totalBytes'] ) ) {
			throw new Ai1wm_Import_Exception( 'Unable to import the archive! Please check file size parameter. ');
		} else if ( $params['totalBytes'] == $params['startBytes'] ) {
			$completed = true;
		}

		// Set completed flag
		$params['completed'] = $completed;

		return $params;
	}
	public static function execute( $params ) {

		$completed = false;

		// Set offset
		if ( ! isset( $params['offset'] ) ) {
			$params['offset'] = 0;
		}

		// Set retry
		if ( ! isset( $params['retry'] ) ) {
			$params['retry'] = 0;
		}

		// Set Gdrive client
		$gdrive = new ServMaskGdriveClient(
			get_option( 'ai1wmge_gdrive_token' ),
			get_option( 'ai1wmge_gdrive_ssl', true )
		);

		// Get archive file
		$archive = fopen( ai1wm_archive_path( $params ), 'rb' );

		// Read file chunk
		if ( ( fseek( $archive, $params['offset'] ) !== -1 )
				&& ( $chunk = fread( $archive, ServMaskGdriveClient::CHUNK_SIZE ) ) ) {

			// Set chunk size
			$params['chunkSize'] = ftell( $archive ) - $params['offset'];

			// Set file size
			$params['fileSize'] = ai1wm_archive_bytes( $params );

			try {
				// Increase number of retries
				$params['retry'] += 1;

				// Upload file chunk
				$gdrive->uploadFileChunk( $chunk, $params );
			} catch ( Exception $e ) {
				// Retry 3 times
				if ( $params['retry'] <= 3 ) {
					return $params;
				}

				throw $e;
			}

			// Reset retry counter
			$params['retry'] = 0;

			// Set archive details
			$name  = ai1wm_archive_name( $params );
			$bytes = ai1wm_archive_bytes( $params );
			$size  = ai1wm_archive_size( $params );

			// Get progress
			if ( isset( $params['offset'] ) ) {
				$progress = (int) ( ( $params['offset'] / $bytes ) * 100 );
			} else {
				$progress = 100;
			}

			// Set progress
			Ai1wm_Status::info( __(
				"<i class=\"ai1wm-icon-gdrive\"></i> " .
				"Uploading <strong>{$name}</strong> ({$size})<br />{$progress}% complete",
				AI1WMGE_PLUGIN_NAME
			) );

		} else {

			// Set last backup date
			update_option( 'ai1wmge_gdrive_timestamp', current_time( 'timestamp' ) );

			// Set progress
			Ai1wm_Status::done(
				__( 'Your WordPress archive has been uploaded to Google Drive.', AI1WMGE_PLUGIN_NAME ),
				__( 'Google Drive', AI1WMGE_PLUGIN_NAME )
			);

			// Upload completed
			$completed = true;

			self::notify_admin_of_new_backup( $params );
		}

		// Close the archive file
		fclose( $archive );

		// Set completed flag
		$params['completed'] = $completed;

		return $params;
	}