نظرة عامة

ملفات البيانات المنظَّمة (SDFs) هي ملفات قيم ومفصولة بفواصل (CSV) بتنسيق خاص تُستخدَم لاسترداد البيانات المتعلقة بموارد "مساحة العرض والفيديو 360" وتعديلها بشكل مجمّع. من خلال "مساحة العرض والفيديو 360 API"، يمكنك إنشاء ملفات SDF مخصّصة وتنزيلها، ما يتيح لك استرداد البيانات المنظّمة والمفلتَرة على موارد "مساحة العرض والفيديو 360".

يشرح هذا الدليل كيفية إنشاء عملية تنزيل SDF وتتبع هذه العملية وتنزيل ملفات SDF الناتجة.

ويمكن العثور على معلومات بشأن تنسيق SDF وتحديد إصداراته في المستندات المرجعية لأداة SDF.

إنشاء مهمّة

يتم إنشاء ملفات SDF عن طريق عملية غير متزامنة تُعرف باسم sdfdownloadtask. عند إنشاء هذه المهمة، تحدد المعلمات المتعلقة بـ SDF المطلوبة. يتم ذلك من خلال طريقة sdfdownloadtasks.create. تصف الأقسام الفرعية التالية المعلمات التي يمكنك ضبطها.

تحديد إصدار

يتم تحديث تنسيق ملف البيانات المنظَّمة بانتظام بشكل مستقل عن "مساحة العرض والفيديو 360 API"، مع طرح الإصدارات الجديدة والقديمة بشكل منتظم. لهذا السبب، ننصح دائمًا باستخدام أحدث إصدار من SDF.

يمكنك ضبط نسخة SDF لـ SDF المطلوب باستخدام الحقل version في نص الطلب. في حال ترك هذه السياسة بدون ضبط أو ضبطها على SDF_VERSION_UNSPECIFIED، سيتم استخدام النسخة التلقائية من أداة SDF الخاصة بالمعلِن أو مورد الشريك والمستخدَمة كسياق لمحتوى SDF.

تحديد السياق

يمكنك إنشاء SDF يتضمن بيانات عن أي موارد متاحة لك، ولكن لا يمكن لأي فردي من المؤسسات التعليمية عرض المحتوى إلا في سياق شريك أو معلن واحد. يتم تحديد هذا السياق في نص الطلب إما عن طريق الحقل partnerId أو advertiserId. يجب تعيين أحد هذين الحقلين بالضبط.

ولن يتم تضمين سوى الموارد المتاحة في السياق المحدّد في ملف SDF الناتج. إذا حاولت الفلترة حسب مورد غير مملوك للشريك أو المعلن المحدّد، لن يتم تضمين هذا المورد أو المحتوى الذي يندرج تحته في النتائج. في حال الفلترة حسب هذه الموارد غير المضمّنة فقط، ستكون الملفات الناتجة فارغة. ولن تؤدي محاولة الفلترة حسب الموارد خارج السياق المحدّد إلى عرض خطأ، لذا احرص على التحقق من صحة السياق.

اختيار الفلتر المناسب

بالإضافة إلى السياق المعيّن أعلاه، يمكنك إجراء فلترة إضافية لنطاق ملفات البيانات المنظَّمة التي تم إنشاؤها، وذلك من خلال تحديد أنواع الملفات التي تريد إنشاءها والموارد أو مجموعة الموارد التي تريد تضمينها.

تتوفّر ثلاثة فلاتر لـ sdfdownloadtask، ويلبّي كل فلتر نوع مواصفات معيّن. يمكنك تعيين نطاق واحد فقط لعنصر sdfdownloadtask واحد.

ParentEntityFilter

ParentEntityFilter هو أوسع نطاق من بين الفلاتر المتاحة.

باستخدام الحقل fileType، يمكنك إدراج جميع أنواع الملفات المطلوبة التي تريد إنشاءها باستخدام مهمتك. هذا الإجراء مطلوب، وفي حال ترك الحقل فارغًا أو ضبط السياسة على FILE_TYPE_UNSPECIFIED، سيتم إكمال sdfdownloadtask بشكل خاطئ.

يمكنك استخدام الحقلَين filterType وfilterIds لتحسين النتائج بشكل أكبر. تحدّد filterType نوع الموارد المطلوب الفلترة حسبها وfilterIds تحدد هذه الموارد من خلال معرّفها الفريد. ستتضمّن إطارات البيانات الرقمية الناتجة الموارد التي تم تحديدها من خلال fileType والتي تمثّل موارد أو عناصر فرعية للموارد المحدّدة في إطار عمل filterType وfilterIds.

IdFilter

يؤدي استخدام IdFilter إلى فلترة طلبك لتضمين الموارد التي تم تحديدها فقط.

تتضمن IdFilter حقلاً لكل نوع من أنواع SDF، باستثناء "مصدر المستودع". كلّ حقل من هذه الحقول هو قائمة بمعرّفات فريدة تحدّد الموارد المحدّدة التي تريد تضمينها في أداة SDF التي تم إنشاؤها. يجب أن تكون المعرفات المقدمة ضمن مجموعة السياق، لكنها لا تحتاج إلى أن تكون مرتبطة بشكل مباشر. لست بحاجة إلى طلب حملة معينة من أجل طلب العنصر الذي تحتوي عليه، والعكس صحيح. ستكون أنواع الملفات الوحيدة التي يتم إنشاؤها هي تلك المتوافقة مع الموارد المحددة في IdFilter.

InventorySourceFilter

لا تسمح السمة InventorySourceFilter إلا بفلترة وتنزيل ملفات SDF التي تتضمّن موارد "مصدر المستودع". إنه الفلتر الوحيد الذي يمكنك استخدامه للحصول على معلومات عن موارد مصدر المستودع.

تحتوي InventorySourceFilter على حقل inventorySourceIds فردي يمكنك من خلاله تحديد المعرّفات الفريدة لموارد مصدر المستودع التي تريد تضمينها في SDF. إذا كانت القائمة المرسَلة إلى inventorySourceIds فارغة، سيتمّ تضمين كل مصادر المستودع ضمن السياق المحدّد في أداة SDF التي تم إنشاؤها.

تقديم طلب

بعد معرفة معلَمات SDF المطلوب، يمكنك إنشاء الطلب وإنشاء sdfdownloadtask.

إليك مثال على كيفية إنشاء sdfdownloadtask باستخدام السمة ParentEntityFilter:

Java

// Create the filter structure
ParentEntityFilter parentEntityFilter = new ParentEntityFilter();
parentEntityFilter.setFileType(sdf-file-type-list);
parentEntityFilter.setFilterType(sdfFilterType);
parentEntityFilter.setFilterIds(filter-id-list);

// Configure the sdfdownloadtasks.create request
Sdfdownloadtasks.Create request =
   service
       .sdfdownloadtasks()
       .create(
           new CreateSdfDownloadTaskRequest()
               .setVersion(sdfVersion)
               .setAdvertiserId(advertiserId)
               .setParentEntityFilter(parentEntityFilter)
       );

// Create the sdfdownloadtask
Operation operationResponse = request.execute();

System.out.printf("Operation %s was created.\n",
   operationResponse.getName());

Python

# Configure the sdfdownloadtasks.create request
createSdfDownloadTaskRequest = {
    'version': sdf-version,
    'advertiserId': advertiser-id,
    'parentEntityFilter': {
        'fileType': sdf-file-type-list,
        'filterType': sdf-filter-type,
        'filterIds': filter-id-list
    }
}

# Create the sdfdownloadtask
operation = service.sdfdownloadtasks().create(
    body=createSdfDownloadTaskRequest).execute();

print("Operation %s was created." % operation["name"])

PHP

// Create the sdfdownloadtasks.create request structure
$createSdfDownloadTaskRequest =
    new Google_Service_DisplayVideo_CreateSdfDownloadTaskRequest();
$createSdfDownloadTaskRequest->setAdvertiserId(advertiser-id);
$createSdfDownloadTaskRequest->setVersion(sdf-version);

// Create and set the parent entity filter
$parentEntityFilter = new Google_Service_DisplayVideo_ParentEntityFilter();
$parentEntityFilter->setFileType(sdf-file-type-list);
$parentEntityFilter->setFilterType(sdf-filter-type);
if (!empty(filter-id-list)) {
    $parentEntityFilter->setFilterIds(filter-id-list);
}
$createSdfDownloadTaskRequest->setParentEntityFilter($parentEntityFilter);

// Call the API, creating the SDF Download Task.
$operation = $this->service->sdfdownloadtasks->create(
    $createSdfDownloadTaskRequest
);

printf('Operation %s was created.\n', $operation->getName());

يُرجى التحقّق من طلبك والحصول على مسار التنزيل.

عند إنشاء sdfdownloadtask، يتم عرض كائن operation. تمثل هذه العملية حالة عملية إنشاء SDF غير المتزامن في وقت الإنشاء. يمكنك التحقّق من العملية لمعرفة ما إذا كانت مكتملة وجاهزة للتنزيل أو واجهت خطأ، باستخدام طريقة sdfdownloadtasks.operations.get.

عند الانتهاء، ستحتوي العملية المعروضة على حقل done غير خالٍ. ستتضمّن العملية النهائية إمّا حقل response أو error. في حال توفّر الحقل error، سيحتوي الحقل error على عنصر Status يحتوي على رمز خطأ ورسالة تعرض تفاصيل الخطأ الذي حدث. في حال توفّر الحقل response، سيحتوي على كائن بقيمة resourceName يحدّد الملف الذي تم إنشاؤه للتنزيل.

في ما يلي مثال على كيفية التحقّق من طلبك باستخدام ميزة التراجع الأُسيّ:

Java

String operationName = operationResponse.getName();

// Configure the Operations.get request
Sdfdownloadtasks.Operations.Get operationRequest =
   service
       .sdfdownloadtasks()
       .operations()
       .get(operationName);

// Configure exponential backoff for checking the status of our operation
ExponentialBackOff backOff = new ExponentialBackOff.Builder()
   .setInitialIntervalMillis(5000) // setting initial interval to five seconds
   .setMaxIntervalMillis(300000)  // setting max interval to five minutes
   .setMaxElapsedTimeMillis(18000000) // setting max elapsed time to five hours
   .build();

while (operationResponse.getDone() == null) {
 long backoffMillis = backOff.nextBackOffMillis();
 if (backoffMillis == ExponentialBackOff.STOP) {
   System.out.printf("The operation has taken more than five hours to
       complete.\n");
   return;
 }
 Thread.sleep(backoffMillis);

 // Get current status of operation
 operationResponse = operationRequest.execute();
}

// Check if the operation finished with an error and return
if (operationResponse.getError() != null) {
 System.out.printf("The operation finished in error with code %s: %s\n",
     operationResponse.getError().getCode(), operationResponse.getError()
         .getMessage());
 return;
}

System.out.printf(
    "The operation completed successfully. Resource %s was created.\n",
    operationResponse.getResponse().get("resourceName").toString());

Python

# The following values control retry behavior while
# the report is processing.
# Minimum amount of time between polling requests. Defaults to 5 seconds.
min_retry_interval = 5
# Maximum amount of time between polling requests. Defaults to 5 minutes.
max_retry_interval = 5 * 60
# Maximum amount of time to spend polling. Defaults to 5 hours.
max_retry_elapsed_time = 5 * 60 * 60

# Configure the Operations.get request
get_request = service.sdfdownloadtasks().operations().get(
  name=operation["name"]
)

sleep = 0
start_time = time.time()
while True:
  # Get current status of operation
  operation = get_request.execute()

  if "done" in operation:
    if "error" in operation:
      print("The operation finished in error with code %s: %s" % (
            operation["error"]["code"],
            operation["error"]["message"]))
    else:
      print("The operation completed successfully. Resource %s was created."
            % operation["response"]["resourceName"])
    break
  elif time.time() - start_time > max_retry_elapsed_time:
    print("Generation deadline exceeded.")

  sleep = next_sleep_interval(sleep)
  print("Operation still running, sleeping for %d seconds." % sleep)
  time.sleep(sleep)

def next_sleep_interval(previous_sleep_interval):
  """Calculates the next sleep interval based on the previous."""
  min_interval = previous_sleep_interval or min_retry_interval
  max_interval = previous_sleep_interval * 3 or min_retry_interval
  return min(max_retry_interval, random.randint(min_interval, max_interval))

PHP

// The following values control retry behavior
// while the task is processing.
// Minimum amount of time between polling requests. Defaults to 5 seconds.
$minRetryInterval = 5;
// Maximum amount of time between polling requests. Defaults to 5 minutes.
$maxRetryInterval = 300;
// Maximum amount of time to spend polling. Defaults to 5 hours.
$maxRetryElapsedTime = 18000;

$operationName = $operation->getName();

$sleepInterval = 0;
$startTime = time();

while (!$operation->getDone()) {
    if ($sleepInterval != 0) {
        printf(
            'The operation is still running, sleeping for %d seconds\n',
            $sleepInterval
        );
    }

    // Sleep before retrieving the SDF Download Task again.
    sleep($sleepInterval);

    // Call the API, retrieving the SDF Download Task.
    $operation = $this->service->sdfdownloadtasks_operations->get(
        $operation->getName()
    );

    // If the operation has exceeded the set deadline, throw an exception.
    if (time() - $startTime > $maxRetryElapsedTime) {
        printf('SDF download task processing deadline exceeded\n');
        throw new Exception(
            'Long-running operation processing deadline exceeded'
        );
    }

    // Generate the next sleep interval using exponential backoff logic.
    $sleepInterval = min(
        $maxRetryInterval,
        rand(
            max($minRetryInterval, $previousSleepInterval),
            max($minRetryInterval, $previousSleepInterval * 3)
        )
    );
}

// If the operation finished with an error, throw an exception.
if($operation->getError() !== null) {
    $error = $operation->getError();
    printf(
        'The operation finished in error with code %s: %s\n',
        $error->getCode(),
        $error->getMessage()
    );
    throw new Exception($error->getMessage());
}

// Print successfully generated resource.
$response = $operation->getResponse();
printf(
    'The operation completed successfully. Resource %s was '
        . 'created. Ready to download.\n',
    $response['resourceName']
);