هذه هي الجولة التفصيلية الرابعة في إضافات Classroom. لسلسلة الجولات التفصيلية.
وفي هذه الجولة التفصيلية، يمكنك التفاعل مع Google Classroom API لإنشاء المرفقات. ويمكنك توفير مسارات للمستخدمين لعرض محتوى المرفق. تشير رسالة الأشكال البيانية تختلف طرق العرض استنادًا إلى دور المستخدم في الفئة. تتناول هذه الجولة التفصيلية المرفقات من نوع المحتوى التي لا تتطلّب أن يرسلها الطالب.
خلال هذه الجولة التفصيلية، يمكنك إكمال ما يلي:
- استرداد مَعلمات طلب البحث الإضافية التالية واستخدامها:
addOnToken
: تم تمرير رمز تفويض مميز إلى "اكتشاف المرفقات" عرض.itemId
: معرّف فريد لـ CourseWork أو CourseWorkMaterial أو إشعار يتلقّى مرفق الإضافةitemType
: إما "courseWork" أو "courseWorkMaterials" أو "إشعار".courseId
: معرّف فريد لدورة Google Classroom في الذي يتم إنشاء المهمة الدراسية.attachmentId
: معرّف فريد يعيّنه Google Classroom لأحد الطلاب مرفق إضافة بعد الإنشاء.
- تنفيذ التخزين الدائم للمرفقات من نوع المحتوى.
- توفير مسارات لإنشاء المرفقات وعرض صور المعلّمين إطارات iframe في العرض للطلاب
- يمكنك إصدار الطلبات التالية لواجهة برمجة تطبيقات إضافات Google Classroom:
- إنشاء مرفق جديد
- احصل على سياق الإضافة، الذي يحدد ما إذا كان المستخدم الذي سجّل الدخول الطالب أو المعلم.
بعد الانتهاء، يمكنك إنشاء مرفقات من نوع المحتوى في المهام من خلال واجهة المستخدم في Google Classroom عند تسجيل الدخول كمعلّم. المعلمون والطلاب في يمكن للفئة أيضًا عرض المحتوى.
تفعيل Classroom API
إجراء اتصالات باستخدام Classroom API بدءًا من هذه الخطوة. يجب أن لمشروعك على Google Cloud قبل أن تتمكن من إجراء مكالمات إليه. التنقّل إلى إدخال مكتبة Google Classroom API واختَر تفعيل.
التعامل مع مَعلمات طلب البحث لعرض استكشاف المرفقات
كما ذكرنا سابقًا، يعمل Google Classroom على تمرير معلَمات طلب البحث عند تحميل طريقة عرض استكشاف المرفقات في إطار iframe:
courseId
: رقم تعريف الدورة التدريبية الحالية في Classroom.itemId
: معرّف فريد لـ CourseWork أو CourseWorkMaterial أو إشعار يتلقّى مرفق الإضافةitemType
: إما "courseWork" أو "courseWorkMaterials" أو "إشعار"addOnToken
: رمز مميز يُستخدم لتفويض بعض إجراءات إضافة Classroomlogin_hint
: رقم تعريف Google للمستخدم الحالي
تتناول هذه الجولة التفصيلية courseId
وitemId
وitemType
وaddOnToken
.
الاحتفاظ بهذه الرموز وتمريرها عند إصدار الطلبات في Classroom API.
وكما في الخطوة التفصيلية السابقة، خزِّن قيم مَعلمات طلب البحث التي تم تمريرها في جلستنا. من المهم أن نفعل ذلك عندما تكون طريقة عرض اكتشاف المرفقات افتتاح لأول مرة، حيث إنها الفرصة الوحيدة التي يمكن من خلالها لتمرير معلمات طلب البحث هذه.
Python
انتقِل إلى ملف خادم Flask الذي يوفّر مسارات للمرفق
طريقة عرض Discovery (attachment-discovery-routes.py
إذا كنت تتابع
المثال المقدم). في أعلى المسار المقصود للإضافة
(/classroom-addon
في المثال المقدَّم)، يتم استرداد وتخزين
مَعلمات طلب البحث courseId
وitemId
وitemType
وaddOnToken
# Retrieve the itemId, courseId, and addOnToken query parameters.
if flask.request.args.get("itemId"):
flask.session["itemId"] = flask.request.args.get("itemId")
if flask.request.args.get("itemType"):
flask.session["itemType"] = flask.request.args.get("itemType")
if flask.request.args.get("courseId"):
flask.session["courseId"] = flask.request.args.get("courseId")
if flask.request.args.get("addOnToken"):
flask.session["addOnToken"] = flask.request.args.get("addOnToken")
اكتب هذه القيم في الجلسة فقط في حال توفّرها. لا يتم تمريره مرة أخرى إذا صادف المستخدم عودة إلى طريقة عرض استكشاف المرفقات لاحقًا بدون إغلاق iframe.
إضافة مساحة تخزين دائمة للمرفقات من نوع المحتوى
يجب توفُّر سجلّ محلي لأي مرفقات تم إنشاؤها. يتيح لك هذا البحث عن المحتوى الذي اختاره المعلّم باستخدام المعرّفات المقدَّمة من Classroom.
عليك إعداد مخطّط قاعدة بيانات لـ Attachment
. يوضح المثال الذي نقدمه
المرفقات التي تعرض صورةً وشرحًا يحتوي Attachment
على
السمات التالية:
attachment_id
: معرّف فريد لمرفق. تم التعيين من قِبل Classroom وظهرت في الرد عند إنشاء المرفق.image_filename
: اسم الملف المحلي للصورة التي تريد عرضهاimage_caption
: الشرح الذي سيتم عرضه مع الصورة
Python
توسيع تنفيذ SQLite وflask_sqlalchemy
من الخطوات السابقة
انتقِل إلى الملف الذي حدّدت جدول المستخدمين فيه (models.py
).
إذا كنت تتبع المثال المقدم). إضافة ما يلي في أسفل الصفحة
من الملف ضمن الفئة User
.
class Attachment(db.Model):
# The attachmentId is the unique identifier for the attachment.
attachment_id = db.Column(db.String(120), primary_key=True)
# The image filename to store.
image_filename = db.Column(db.String(120))
# The image caption to store.
image_caption = db.Column(db.String(120))
قم باستيراد فئة المرفقات الجديدة إلى ملف الخادم الذي يحتوي على المرفق مسارات المناولة.
إعداد مسارات جديدة
ابدأ هذه الجولة التفصيلية بإعداد بعض الصفحات الجديدة في تطبيقنا. وتتيح هذه الإضافات للمستخدم إنشاء المحتوى وعرضه من خلال إضافتنا.
إضافة مسارات إنشاء المرفقات
تحتاج إلى صفحات ليختار المعلّم المحتوى وينشئ المرفقات.
الطلبات. تنفيذ المسار /attachment-options
لعرض خيارات المحتوى
ليختاره المعلّم. تحتاج أيضًا إلى قوالب لاختيار المحتوى
صفحات تأكيد الإنشاء. تحتوي أمثلتنا المقدمة على نماذج لهذه
ويمكنك أيضًا عرض الطلبات والردود من
Classroom API.
لاحظ أنه يمكنك بدلاً من ذلك تعديل طريقة عرض استكشاف المرفقات الحالية
المقصودة لعرض خيارات المحتوى بدلاً من إنشاء الصفحة
صفحة واحدة (/attachment-options
). ننصحك بإنشاء صفحة جديدة لأغراض
هذا التمرين حتى تحافظ على تنفيذ سلوك الدخول الموحّد الذي تم تنفيذه في
للحصول على جولة تفصيلية، مثل إبطال أذونات التطبيق يجب أن تثبت هذه
فائدة أثناء إنشاء الوظيفة الإضافية واختبارها.
يمكن للمعلّم الاختيار من بين مجموعة صغيرة من الصور التي تتضمّن ترجمة وشرحًا في الفيديوهات المقدَّمة. مثال. لقد قدمنا أربع صور لمعالم شهيرة مشتقة من أسماء الملفات.
Python
في المثال الذي قدمناه، ستجد ذلك في ملف webapp/attachment_routes.py
.
@app.route("/attachment-options", methods=["GET", "POST"])
def attachment_options():
"""
Render the attachment options page from the "attachment-options.html"
template.
This page displays a grid of images that the user can select using
checkboxes.
"""
# A list of the filenames in the static/images directory.
image_filenames = os.listdir(os.path.join(app.static_folder, "images"))
# The image_list_form_builder method creates a form that displays a grid
# of images, checkboxes, and captions with a Submit button. All images
# passed in image_filenames will be shown, and the captions will be the
# title-cased filenames.
# The form must be built dynamically due to limitations in WTForms. The
# image_list_form_builder method therefore also returns a list of
# attribute names in the form, which will be used by the HTML template
# to properly render the form.
form, var_names = image_list_form_builder(image_filenames)
# If the form was submitted, validate the input and create the attachments.
if form.validate_on_submit():
# Build a dictionary that maps image filenames to captions.
# There will be one dictionary entry per selected item in the form.
filename_caption_pairs = construct_filename_caption_dictionary_list(
form)
# Check that the user selected at least one image, then proceed to
# make requests to the Classroom API.
if len(filename_caption_pairs) > 0:
return create_attachments(filename_caption_pairs)
else:
return flask.render_template(
"create-attachment.html",
message="You didn't select any images.",
form=form,
var_names=var_names)
return flask.render_template(
"attachment-options.html",
message=("You've reached the attachment options page. "
"Select one or more images and click 'Create Attachment'."),
form=form,
var_names=var_names,
)
وينتج عن ذلك "إنشاء مرفقات" تشبه ما يلي:
يمكن للمعلّم اختيار عدة صور. إنشاء مرفق واحد لكل صورة
التي اختارها المعلّم في طريقة create_attachments
مشاكل في طلبات إنشاء المرفقات
الآن بعد أن عرفت أجزاء المحتوى التي يرغب المعلم في إرفاقها، الطلبات إلى واجهة Classroom API لإنشاء مرفقات مهمة معينة. تخزين تفاصيل المرفق في قاعدة البيانات الخاصة بك بعد تلقي الرد من Classroom API.
ابدأ بالحصول على مثيل لخدمة Classroom:
Python
في المثال الذي قدمناه، ستجد ذلك في ملف webapp/attachment_routes.py
.
def create_attachments(filename_caption_pairs):
"""
Create attachments and show an acknowledgement page.
Args:
filename_caption_pairs: A dictionary that maps image filenames to
captions.
"""
# Get the Google Classroom service.
classroom_service = googleapiclient.discovery.build(
serviceName="classroom",
version="v1",
credentials=credentials)
إرسال طلب "CREATE
" إلى courses.courseWork.addOnAttachments
النهائية. لكل صورة يحددها المدرس، أنشئ أولاً
كائن AddOnAttachment
:
Python
في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments
.
.
# Create a new attachment for each image that was selected.
attachment_count = 0
for key, value in filename_caption_pairs.items():
attachment_count += 1
# Create a dictionary with values for the AddOnAttachment object fields.
attachment = {
# Specifies the route for a teacher user.
"teacherViewUri": {
"uri":
flask.url_for(
"load_content_attachment", _scheme='https', _external=True),
},
# Specifies the route for a student user.
"studentViewUri": {
"uri":
flask.url_for(
"load_content_attachment", _scheme='https', _external=True)
},
# The title of the attachment.
"title": f"Attachment {attachment_count}",
}
يجب أن تكون الحقول teacherViewUri
وstudentViewUri
وtitle
على الأقل:
المقدمة لكل مرفق. teacherViewUri
وstudentViewUri
لتمثيل عناوين URL التي تم تحميلها عند فتح المرفق من خلال
ونوع المستخدم المعني.
إرسال عنصر AddOnAttachment
في نص الطلب إلى الجهة المناسبة
نقطة نهاية addOnAttachments
. أدخِل courseId
وitemId
وitemType
addOnToken
معرّفات لكل طلب.
Python
في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments
.
.
# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
case "announcements":
parent = classroom_service.courses().announcements()
case "courseWorkMaterials":
parent = classroom_service.courses().courseWorkMaterials()
case _:
parent = classroom_service.courses().courseWork()
# Issue a request to create the attachment.
resp = parent.addOnAttachments().create(
courseId=flask.session["courseId"],
itemId=flask.session["itemId"],
addOnToken=flask.session["addOnToken"],
body=attachment).execute()
أنشئ إدخالاً لهذا المرفق في قاعدة البيانات المحلية الخاصة بك حتى تتمكن من ذلك لاحقًا
لتحميل المحتوى الصحيح. يعرض Classroom قيمة فريدة للسمة id
في الرد على طلب الإنشاء، لذا استخدمه كمفتاح أساسي في
قاعدة البيانات. تجدر الإشارة أيضًا إلى أنّ Classroom يجتاز attachmentId
.
معلَمة طلب البحث عند فتح طرق عرض المعلم والطالب:
Python
في المثال الذي قدّمناه، نواصل هذا العمل كمواصلة للّعبة create_attachments
.
.
# Store the value by id.
new_attachment = Attachment(
# The new attachment's unique ID, returned in the CREATE response.
attachment_id=resp.get("id"),
image_filename=key,
image_caption=value)
db.session.add(new_attachment)
db.session.commit()
يمكنك توجيه المستخدم إلى صفحة تأكيد في هذه المرحلة، مع الإقرار من أنه تم إنشاء المرفقات بنجاح.
السماح بالمرفقات من الإضافة
حان الوقت الآن لإضافة أي عناوين مناسبة إلى المرفق المسموح به حقل بادئات معرِّف الموارد المنتظم (URI) في إعداد التطبيق ضمن حزمة تطوير البرامج (SDK) في Google Workspace Marketplace . يمكن لإضافتك إنشاء مرفقات من إحدى بادئات معرّف الموارد المنتظم (URI) فقط. مدرجة في هذه الصفحة. هذا إجراء أمني للمساعدة في تقليل احتمالية من هجمات الوسيط.
وأبسط طريقة هي تقديم نطاق المستوى الأعلى في هذا الحقل،
مثال https://example.com
الإجراء الذي سينفّذه https://localhost:<your port number>/
إذا كنت تستخدم جهازك المحلي كخادم الويب.
إضافة مسارات لطرق عرض المعلّمين والطلاب
هناك أربعة إطارات iframe يمكن تحميل إضافة Google Classroom فيها. لقد أنشأت فقط مسارات تعرض إطار iframe لعرض المرفقات، وبالتالي بعيد. بعد ذلك، أضف مسارات لخدمة إطارات iframe الخاصة بعرض المعلم والطلاب أيضًا.
يجب توفّر إطار iframe لمشاهدة المعلّمين لعرض معاينة للطالب المستخدم، ولكن يمكن أن تتضمن اختياريًا معلومات أو تعديلات إضافية الجديدة.
طريقة عرض الطالب هي الصفحة التي يتم تقديمها لكل طالب عند فتحه. مرفق إضافة.
لأغراض هذا التمرين، أنشئ /load-content-attachment
واحدًا.
الذي يخدم كلاً من طريقة عرض المعلم والطلاب. استخدام Classroom API
لتحديد ما إذا كان المستخدم مدرسًا أو طالبًا عند عرض صفحة
التحميل.
Python
في المثال الذي قدمناه، ستجد ذلك في ملف webapp/attachment_routes.py
.
@app.route("/load-content-attachment")
def load_content_attachment():
"""
Load the attachment for the user's role."""
# Since this is a landing page for the Teacher and Student View iframes, we
# need to preserve the incoming query parameters.
if flask.request.args.get("itemId"):
flask.session["itemId"] = flask.request.args.get("itemId")
if flask.request.args.get("itemType"):
flask.session["itemType"] = flask.request.args.get("itemType")
if flask.request.args.get("courseId"):
flask.session["courseId"] = flask.request.args.get("courseId")
if flask.request.args.get("attachmentId"):
flask.session["attachmentId"] = flask.request.args.get("attachmentId")
ضع في اعتبارك أنه يجب أيضًا مصادقة المستخدم في هذه المرحلة. إِنْتَ
أيضًا التعامل مع معلَمة طلب البحث login_hint
هنا، وتوجيه المستخدم إلى
تدفق التفويض إذا لزم الأمر. يمكنك الاطّلاع على تفاصيل إرشادات تسجيل الدخول التي تمت مناقشتها
في الجولات التفصيلية السابقة لمزيد من المعلومات حول هذا المسار.
بعد ذلك، يمكنك إرسال طلب إلى نقطة النهاية getAddOnContext
التي تتطابق مع العنصر.
الكتابة.
Python
في المثال الذي قدمناه، يعد ذلك استمرارًا
طريقة load_content_attachment
.
# Create an instance of the Classroom service.
classroom_service = googleapiclient.discovery.build(
serviceName="classroom"
version="v1",
credentials=credentials)
# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
case "announcements":
parent = classroom_service.courses().announcements()
case "courseWorkMaterials":
parent = classroom_service.courses().courseWorkMaterials()
case _:
parent = classroom_service.courses().courseWork()
addon_context_response = parent.getAddOnContext(
courseId=flask.session["courseId"],
itemId=flask.session["itemId"]).execute()
تعرض هذه الطريقة معلومات حول دور المستخدم الحالي في الفئة.
ويمكنك تغيير طريقة العرض المعروضة للمستخدم حسب دوره. واحد بالضبط من
تعبئة حقل studentContext
أو teacherContext
في الرد
. افحصها لتحديد كيفية التعامل مع المستخدم.
على أي حال، استخدِم قيمة مَعلمة طلب البحث attachmentId
لمعرفة أيّ
مرفق لاستردادها من قاعدة البيانات لدينا. يتم توفير معلمة طلب البحث هذه عندما
فتح معرفات الموارد المنتظمة (URI) لعرض المعلم أو الطالب.
Python
في المثال الذي قدمناه، يعد ذلك استمرارًا
طريقة load_content_attachment
.
# Determine which view we are in by testing the returned context type.
user_context = "student" if addon_context_response.get(
"studentContext") else "teacher"
# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])
# Set the text for the next page depending on the user's role.
message_str = f"I see that you're a {user_context}! "
message_str += (
f"I've loaded the attachment with ID {attachment.attachment_id}. "
if user_context == "teacher" else
"Please enjoy this image of a famous landmark!")
# Show the content with the customized message text.
return flask.render_template(
"show-content-attachment.html",
message=message_str,
image_filename=attachment.image_filename,
image_caption=attachment.image_caption,
responses=response_strings)
اختبار الإضافة
أكمِل الخطوات التالية لاختبار إنشاء المرفق:
- تسجيل الدخول إلى [Google Classroom] كأحد مستخدمو اختبار المعلّمين
- انتقِل إلى علامة التبويب الواجب الدراسي وأنشئ مهمة جديدة.
- انقر على الزر الإضافات أسفل مربّع النص، ثم اختَر الإضافة التي تريدها. يفتح إطار iframe ويحمّل الإضافة معرّف الموارد المنتظم (URI) لإعداد المرفق الذي المحدّدة في صفحة إعداد التطبيق ضمن حزمة تطوير البرامج (SDK) في Google Workspace Marketplace.
- اختر جزءًا من المحتوى لإرفاقه بالمهمة.
- يمكنك إغلاق إطار iframe بعد اكتمال عملية إنشاء المرفقات.
من المفترَض أن تظهر لك بطاقة مرفق في واجهة مستخدم إنشاء المهمة في Google. Google Classroom انقر على البطاقة لفتح إطار iframe لميزة "عرض المعلّمين" وتأكيد العملية. ليظهر المرفق الصحيح. انقر على الزر تعيين.
أكمِل الخطوات التالية لاختبار تجربة الطالب:
- بعد ذلك، سجِّل الدخول إلى Classroom كمستخدم اختباري للطلاب على الصف كمستخدم اختبار المعلم.
- ابحث عن المهمة الاختبارية في علامة التبويب "الواجب الدراسي".
- توسيع المهمة والنقر على البطاقة المُرفقة لفتح "طريقة عرض الطالب" iframe.
تأكَّد من ظهور المرفق الصحيح للطالب.
تهانينا! يمكنك الآن المتابعة إلى الخطوة التالية: إنشاء المرفقات من نوع النشاط