1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2016 Canonical Ltd.
4 * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.1+
7 */
8
9 /**
10 * SECTION:as-review
11 * @title: AsReview
12 * @include: appstream-glib.h
13 * @stability: Stable
14 * @short_description: An application user review
15 *
16 * This object represents a user-submitted application review.
17 *
18 * Since: 0.6.1
19 **/
20
21 #include "config.h"
22
23 #include "as-review-private.h"
24 #include "as-node-private.h"
25 #include "as-ref-string.h"
26 #include "as-utils-private.h"
27 #include "as-yaml.h"
28
29 typedef struct
30 {
31 AsReviewFlags flags;
32 AsRefString *id;
33 AsRefString *summary;
34 AsRefString *description;
35 AsRefString *locale;
36 gint priority;
37 gint rating;
38 AsRefString *version;
39 AsRefString *reviewer_id;
40 AsRefString *reviewer_name;
41 GDateTime *date;
42 GHashTable *metadata; /* AsRefString : AsRefString */
43 } AsReviewPrivate;
44
45 enum {
46 PROP_0,
47 PROP_ID,
48 PROP_SUMMARY,
49 PROP_DESCRIPTION,
50 PROP_LOCALE,
51 PROP_RATING,
52 PROP_VERSION,
53 PROP_REVIEWER_ID,
54 PROP_REVIEWER_NAME,
55 PROP_DATE,
56 PROP_FLAGS,
57 PROP_LAST
58 };
59
G_DEFINE_TYPE_WITH_PRIVATE(AsReview,as_review,G_TYPE_OBJECT)60 G_DEFINE_TYPE_WITH_PRIVATE (AsReview, as_review, G_TYPE_OBJECT)
61
62 #define GET_PRIVATE(o) (as_review_get_instance_private (o))
63
64 static void
65 as_review_finalize (GObject *object)
66 {
67 AsReview *review = AS_REVIEW (object);
68 AsReviewPrivate *priv = GET_PRIVATE (review);
69
70 if (priv->id != NULL)
71 as_ref_string_unref (priv->id);
72 if (priv->summary != NULL)
73 as_ref_string_unref (priv->summary);
74 if (priv->description != NULL)
75 as_ref_string_unref (priv->description);
76 if (priv->locale != NULL)
77 as_ref_string_unref (priv->locale);
78 if (priv->version != NULL)
79 as_ref_string_unref (priv->version);
80 if (priv->reviewer_id != NULL)
81 as_ref_string_unref (priv->reviewer_id);
82 if (priv->reviewer_name != NULL)
83 as_ref_string_unref (priv->reviewer_name);
84 g_hash_table_unref (priv->metadata);
85 if (priv->date != NULL)
86 g_date_time_unref (priv->date);
87
88 G_OBJECT_CLASS (as_review_parent_class)->finalize (object);
89 }
90
91 static void
as_review_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)92 as_review_get_property (GObject *object, guint prop_id,
93 GValue *value, GParamSpec *pspec)
94 {
95 AsReview *review = AS_REVIEW (object);
96 AsReviewPrivate *priv = GET_PRIVATE (review);
97
98 switch (prop_id) {
99 case PROP_ID:
100 g_value_set_string (value, priv->id);
101 break;
102 case PROP_SUMMARY:
103 g_value_set_string (value, priv->summary);
104 break;
105 case PROP_DESCRIPTION:
106 g_value_set_string (value, priv->description);
107 break;
108 case PROP_LOCALE:
109 g_value_set_string (value, priv->locale);
110 break;
111 case PROP_RATING:
112 g_value_set_int (value, priv->rating);
113 break;
114 case PROP_FLAGS:
115 g_value_set_uint64 (value, priv->flags);
116 break;
117 case PROP_VERSION:
118 g_value_set_string (value, priv->version);
119 break;
120 case PROP_REVIEWER_ID:
121 g_value_set_string (value, priv->reviewer_id);
122 break;
123 case PROP_REVIEWER_NAME:
124 g_value_set_string (value, priv->reviewer_name);
125 break;
126 case PROP_DATE:
127 g_value_set_object (value, priv->date);
128 break;
129 default:
130 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
131 break;
132 }
133 }
134
135 static void
as_review_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)136 as_review_set_property (GObject *object, guint prop_id,
137 const GValue *value, GParamSpec *pspec)
138 {
139 AsReview *review = AS_REVIEW (object);
140
141 switch (prop_id) {
142 case PROP_ID:
143 as_review_set_id (review, g_value_get_string (value));
144 break;
145 case PROP_SUMMARY:
146 as_review_set_summary (review, g_value_get_string (value));
147 break;
148 case PROP_DESCRIPTION:
149 as_review_set_description (review, g_value_get_string (value));
150 break;
151 case PROP_LOCALE:
152 as_review_set_locale (review, g_value_get_string (value));
153 break;
154 case PROP_RATING:
155 as_review_set_rating (review, g_value_get_int (value));
156 break;
157 case PROP_FLAGS:
158 as_review_set_flags (review, g_value_get_uint64 (value));
159 break;
160 case PROP_VERSION:
161 as_review_set_version (review, g_value_get_string (value));
162 break;
163 case PROP_REVIEWER_ID:
164 as_review_set_reviewer_id (review, g_value_get_string (value));
165 break;
166 case PROP_REVIEWER_NAME:
167 as_review_set_reviewer_name (review, g_value_get_string (value));
168 break;
169 case PROP_DATE:
170 as_review_set_date (review, g_value_get_object (value));
171 break;
172 default:
173 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
174 break;
175 }
176 }
177
178 static void
as_review_class_init(AsReviewClass * klass)179 as_review_class_init (AsReviewClass *klass)
180 {
181 GParamSpec *pspec;
182 GObjectClass *object_class = G_OBJECT_CLASS (klass);
183 object_class->finalize = as_review_finalize;
184 object_class->get_property = as_review_get_property;
185 object_class->set_property = as_review_set_property;
186
187 /**
188 * AsReview:id:
189 *
190 * Since: 0.6.1
191 **/
192 pspec = g_param_spec_string ("id", NULL, NULL,
193 NULL,
194 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
195 g_object_class_install_property (object_class, PROP_ID, pspec);
196
197 /**
198 * AsReview:summary:
199 *
200 * Since: 0.6.1
201 **/
202 pspec = g_param_spec_string ("summary", NULL, NULL,
203 NULL,
204 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
205 g_object_class_install_property (object_class, PROP_SUMMARY, pspec);
206
207 /**
208 * AsReview:description:
209 *
210 * Since: 0.6.1
211 **/
212 pspec = g_param_spec_string ("description", NULL, NULL,
213 NULL,
214 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
215 g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
216
217 /**
218 * AsReview:locale:
219 *
220 * Since: 0.6.1
221 **/
222 pspec = g_param_spec_string ("locale", NULL, NULL,
223 NULL,
224 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
225 g_object_class_install_property (object_class, PROP_LOCALE, pspec);
226
227 /**
228 * AsReview:rating:
229 *
230 * Since: 0.6.1
231 **/
232 pspec = g_param_spec_int ("rating", NULL, NULL,
233 -1, 100, 0,
234 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
235 g_object_class_install_property (object_class, PROP_RATING, pspec);
236
237 /**
238 * AsReview:flags:
239 *
240 * Since: 0.6.1
241 **/
242 pspec = g_param_spec_uint64 ("flags", NULL, NULL,
243 AS_REVIEW_FLAG_NONE,
244 AS_REVIEW_FLAG_LAST,
245 AS_REVIEW_FLAG_NONE,
246 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
247 g_object_class_install_property (object_class, PROP_FLAGS, pspec);
248
249 /**
250 * AsReview:version:
251 *
252 * Since: 0.6.1
253 **/
254 pspec = g_param_spec_string ("version", NULL, NULL,
255 NULL,
256 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
257 g_object_class_install_property (object_class, PROP_VERSION, pspec);
258
259 /**
260 * AsReview:reviewer-id:
261 *
262 * Since: 0.6.1
263 **/
264 pspec = g_param_spec_string ("reviewer-id", NULL, NULL,
265 NULL,
266 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
267 g_object_class_install_property (object_class, PROP_REVIEWER_ID, pspec);
268
269 /**
270 * AsReview:reviewer-name:
271 *
272 * Since: 0.6.1
273 **/
274 pspec = g_param_spec_string ("reviewer-name", NULL, NULL,
275 NULL,
276 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
277 g_object_class_install_property (object_class, PROP_REVIEWER_NAME, pspec);
278
279 /**
280 * AsReview:date:
281 *
282 * Since: 0.6.1
283 **/
284 pspec = g_param_spec_object ("date", NULL, NULL,
285 AS_TYPE_REVIEW,
286 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
287 g_object_class_install_property (object_class, PROP_DATE, pspec);
288 }
289
290 static void
as_review_init(AsReview * review)291 as_review_init (AsReview *review)
292 {
293 AsReviewPrivate *priv = GET_PRIVATE (review);
294 priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
295 (GDestroyNotify) as_ref_string_unref,
296 (GDestroyNotify) as_ref_string_unref);
297 }
298
299 /**
300 * as_review_get_priority:
301 * @review: a #AsReview
302 *
303 * This allows the UI to sort reviews into the correct order.
304 * Higher numbers indicate a more important or relevant review.
305 *
306 * Returns: the review priority, or 0 for unset.
307 *
308 * Since: 0.6.1
309 **/
310 gint
as_review_get_priority(AsReview * review)311 as_review_get_priority (AsReview *review)
312 {
313 AsReviewPrivate *priv = GET_PRIVATE (review);
314 g_return_val_if_fail (AS_IS_REVIEW (review), 0);
315 return priv->priority;
316 }
317
318 /**
319 * as_review_set_priority:
320 * @review: a #AsReview
321 * @priority: a priority value
322 *
323 * Sets the priority for the review, where positive numbers indicate
324 * a better review for the specific user.
325 *
326 * Since: 0.6.1
327 **/
328 void
as_review_set_priority(AsReview * review,gint priority)329 as_review_set_priority (AsReview *review, gint priority)
330 {
331 AsReviewPrivate *priv = GET_PRIVATE (review);
332 g_return_if_fail (AS_IS_REVIEW (review));
333 priv->priority = priority;
334 }
335
336 /**
337 * as_review_get_id:
338 * @review: a #AsReview
339 *
340 * Gets the review id.
341 *
342 * Returns: the review identifier, e.g. "deadbeef"
343 *
344 * Since: 0.6.1
345 **/
346 const gchar *
as_review_get_id(AsReview * review)347 as_review_get_id (AsReview *review)
348 {
349 AsReviewPrivate *priv = GET_PRIVATE (review);
350 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
351 return priv->id;
352 }
353
354 /**
355 * as_review_get_summary:
356 * @review: a #AsReview
357 *
358 * Gets the review summary.
359 *
360 * Returns: the one-line summary, e.g. "Awesome application"
361 *
362 * Since: 0.6.1
363 **/
364 const gchar *
as_review_get_summary(AsReview * review)365 as_review_get_summary (AsReview *review)
366 {
367 AsReviewPrivate *priv = GET_PRIVATE (review);
368 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
369 return priv->summary;
370 }
371
372 /**
373 * as_review_set_id:
374 * @review: a #AsReview
375 * @id: review identifier, e.g. "deadbeef"
376 *
377 * Sets the review identifier that is unique to each review.
378 *
379 * Since: 0.6.1
380 **/
381 void
as_review_set_id(AsReview * review,const gchar * id)382 as_review_set_id (AsReview *review, const gchar *id)
383 {
384 AsReviewPrivate *priv = GET_PRIVATE (review);
385 g_return_if_fail (AS_IS_REVIEW (review));
386 as_ref_string_assign_safe (&priv->id, id);
387 }
388
389 /**
390 * as_review_set_summary:
391 * @review: a #AsReview
392 * @summary: a one-line summary, e.g. "Awesome application"
393 *
394 * Sets the one-line summary that may be displayed in bold.
395 *
396 * Since: 0.6.1
397 **/
398 void
as_review_set_summary(AsReview * review,const gchar * summary)399 as_review_set_summary (AsReview *review, const gchar *summary)
400 {
401 AsReviewPrivate *priv = GET_PRIVATE (review);
402 g_return_if_fail (AS_IS_REVIEW (review));
403 as_ref_string_assign_safe (&priv->summary, summary);
404 }
405
406 /**
407 * as_review_get_description:
408 * @review: a #AsReview
409 *
410 * Gets the multi-line review text that forms the body of the review.
411 *
412 * Returns: the string, or %NULL
413 *
414 * Since: 0.6.1
415 **/
416 const gchar *
as_review_get_description(AsReview * review)417 as_review_get_description (AsReview *review)
418 {
419 AsReviewPrivate *priv = GET_PRIVATE (review);
420 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
421 return priv->description;
422 }
423
424 /**
425 * as_review_set_description:
426 * @review: a #AsReview
427 * @description: multi-line description
428 *
429 * Sets the multi-line review text that forms the body of the review.
430 *
431 * Since: 0.6.1
432 **/
433 void
as_review_set_description(AsReview * review,const gchar * description)434 as_review_set_description (AsReview *review, const gchar *description)
435 {
436 AsReviewPrivate *priv = GET_PRIVATE (review);
437 g_return_if_fail (AS_IS_REVIEW (review));
438 as_ref_string_assign_safe (&priv->description, description);
439 }
440
441 /**
442 * as_review_get_locale:
443 * @review: a #AsReview
444 *
445 * Gets the locale for the review.
446 *
447 * Returns: the string, or %NULL
448 *
449 * Since: 0.6.1
450 **/
451 const gchar *
as_review_get_locale(AsReview * review)452 as_review_get_locale (AsReview *review)
453 {
454 AsReviewPrivate *priv = GET_PRIVATE (review);
455 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
456 return priv->locale;
457 }
458
459 /**
460 * as_review_set_locale:
461 * @review: a #AsReview
462 * @locale: locale, e.g. "en_GB"
463 *
464 * Sets the locale for the review.
465 *
466 * Since: 0.6.1
467 **/
468 void
as_review_set_locale(AsReview * review,const gchar * locale)469 as_review_set_locale (AsReview *review, const gchar *locale)
470 {
471 AsReviewPrivate *priv = GET_PRIVATE (review);
472 g_return_if_fail (AS_IS_REVIEW (review));
473 as_ref_string_assign_safe (&priv->locale, locale);
474 }
475
476 /**
477 * as_review_get_rating:
478 * @review: a #AsReview
479 *
480 * Gets the star rating of the review, where 100 is 5 stars.
481 *
482 * Returns: integer as a percentage, or 0 for unset
483 *
484 * Since: 0.6.1
485 **/
486 gint
as_review_get_rating(AsReview * review)487 as_review_get_rating (AsReview *review)
488 {
489 AsReviewPrivate *priv = GET_PRIVATE (review);
490 g_return_val_if_fail (AS_IS_REVIEW (review), 0);
491 return priv->rating;
492 }
493
494 /**
495 * as_review_set_rating:
496 * @review: a #AsReview
497 * @rating: a integer as a percentage, or 0 for unset
498 *
499 * Sets the star rating of the review, where 100 is 5 stars..
500 *
501 * Since: 0.6.1
502 **/
503 void
as_review_set_rating(AsReview * review,gint rating)504 as_review_set_rating (AsReview *review, gint rating)
505 {
506 AsReviewPrivate *priv = GET_PRIVATE (review);
507 g_return_if_fail (AS_IS_REVIEW (review));
508 priv->rating = rating;
509 }
510
511 /**
512 * as_review_get_flags:
513 * @review: a #AsReview
514 *
515 * Gets any flags set on the review, for example if the user has already
516 * voted on the review or if the user wrote the review themselves.
517 *
518 * Returns: a #AsReviewFlags, e.g. %AS_REVIEW_FLAG_SELF
519 *
520 * Since: 0.6.1
521 **/
522 AsReviewFlags
as_review_get_flags(AsReview * review)523 as_review_get_flags (AsReview *review)
524 {
525 AsReviewPrivate *priv = GET_PRIVATE (review);
526 g_return_val_if_fail (AS_IS_REVIEW (review), AS_REVIEW_FLAG_NONE);
527 return priv->flags;
528 }
529
530 /**
531 * as_review_set_flags:
532 * @review: a #AsReview
533 * @flags: a #AsReviewFlags, e.g. %AS_REVIEW_FLAG_SELF
534 *
535 * Gets any flags set on the review, for example if the user has already
536 * voted on the review or if the user wrote the review themselves.
537 *
538 * Since: 0.6.1
539 **/
540 void
as_review_set_flags(AsReview * review,AsReviewFlags flags)541 as_review_set_flags (AsReview *review, AsReviewFlags flags)
542 {
543 AsReviewPrivate *priv = GET_PRIVATE (review);
544 g_return_if_fail (AS_IS_REVIEW (review));
545 priv->flags = flags;
546 }
547
548 /**
549 * as_review_add_flags:
550 * @review: a #AsReview
551 * @flags: a #AsReviewFlags, e.g. %AS_REVIEW_FLAG_SELF
552 *
553 * Adds flags to an existing review without replacing the other flags.
554 *
555 * Since: 0.6.1
556 **/
557 void
as_review_add_flags(AsReview * review,AsReviewFlags flags)558 as_review_add_flags (AsReview *review, AsReviewFlags flags)
559 {
560 AsReviewPrivate *priv = GET_PRIVATE (review);
561 g_return_if_fail (AS_IS_REVIEW (review));
562 priv->flags |= flags;
563 }
564
565 /**
566 * as_review_get_reviewer_id:
567 * @review: a #AsReview
568 *
569 * Gets the name of the reviewer.
570 *
571 * Returns: the reviewer ID, e.g. "deadbeef", or %NULL
572 *
573 * Since: 0.6.1
574 **/
575 const gchar *
as_review_get_reviewer_id(AsReview * review)576 as_review_get_reviewer_id (AsReview *review)
577 {
578 AsReviewPrivate *priv = GET_PRIVATE (review);
579 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
580 return priv->reviewer_id;
581 }
582
583 /**
584 * as_review_get_reviewer_name:
585 * @review: a #AsReview
586 *
587 * Gets the name of the reviewer.
588 *
589 * Returns: the reviewer name, e.g. "David Smith", or %NULL
590 *
591 * Since: 0.6.1
592 **/
593 const gchar *
as_review_get_reviewer_name(AsReview * review)594 as_review_get_reviewer_name (AsReview *review)
595 {
596 AsReviewPrivate *priv = GET_PRIVATE (review);
597 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
598 return priv->reviewer_name;
599 }
600
601 /**
602 * as_review_set_reviewer_id:
603 * @review: a #AsReview
604 * @reviewer_id: the reviewer ID, e.g. "deadbeef"
605 *
606 * Sets the name of the reviewer, which can be left unset.
607 *
608 * Since: 0.6.1
609 **/
610 void
as_review_set_reviewer_id(AsReview * review,const gchar * reviewer_id)611 as_review_set_reviewer_id (AsReview *review, const gchar *reviewer_id)
612 {
613 AsReviewPrivate *priv = GET_PRIVATE (review);
614 g_return_if_fail (AS_IS_REVIEW (review));
615 as_ref_string_assign_safe (&priv->reviewer_id, reviewer_id);
616 }
617
618 /**
619 * as_review_set_reviewer_name:
620 * @review: a #AsReview
621 * @reviewer_name: the reviewer name, e.g. "David Smith"
622 *
623 * Sets the name of the reviewer, which can be left unset.
624 *
625 * Since: 0.6.1
626 **/
627 void
as_review_set_reviewer_name(AsReview * review,const gchar * reviewer_name)628 as_review_set_reviewer_name (AsReview *review, const gchar *reviewer_name)
629 {
630 AsReviewPrivate *priv = GET_PRIVATE (review);
631 g_return_if_fail (AS_IS_REVIEW (review));
632 as_ref_string_assign_safe (&priv->reviewer_name, reviewer_name);
633 }
634
635 /**
636 * as_review_set_version:
637 * @review: a #AsReview
638 * @version: a version string, e.g. "0.1.2"
639 *
640 * Sets the version string for the application being reviewed.
641 *
642 * Since: 0.6.1
643 **/
644 void
as_review_set_version(AsReview * review,const gchar * version)645 as_review_set_version (AsReview *review, const gchar *version)
646 {
647 AsReviewPrivate *priv = GET_PRIVATE (review);
648 g_return_if_fail (AS_IS_REVIEW (review));
649 as_ref_string_assign_safe (&priv->version, version);
650 }
651
652 /**
653 * as_review_get_version:
654 * @review: a #AsReview
655 *
656 * Gets the version string for the application being reviewed..
657 *
658 * Returns: the version string, e.g. "0.1.2", or %NULL for unset
659 *
660 * Since: 0.6.1
661 **/
662 const gchar *
as_review_get_version(AsReview * review)663 as_review_get_version (AsReview *review)
664 {
665 AsReviewPrivate *priv = GET_PRIVATE (review);
666 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
667 return priv->version;
668 }
669
670 /**
671 * as_review_get_date:
672 * @review: a #AsReview
673 *
674 * Gets the date the review was originally submitted.
675 *
676 * Returns: (transfer none): the #GDateTime, or %NULL for unset
677 *
678 * Since: 0.6.1
679 **/
680 GDateTime *
as_review_get_date(AsReview * review)681 as_review_get_date (AsReview *review)
682 {
683 AsReviewPrivate *priv = GET_PRIVATE (review);
684 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
685 return priv->date;
686 }
687
688 /**
689 * as_review_set_date:
690 * @review: a #AsReview
691 * @date: a #GDateTime, or %NULL
692 *
693 * Sets the date the review was originally submitted.
694 *
695 * Since: 0.6.1
696 **/
697 void
as_review_set_date(AsReview * review,GDateTime * date)698 as_review_set_date (AsReview *review, GDateTime *date)
699 {
700 AsReviewPrivate *priv = GET_PRIVATE (review);
701 g_return_if_fail (AS_IS_REVIEW (review));
702 g_clear_pointer (&priv->date, g_date_time_unref);
703 if (date != NULL)
704 priv->date = g_date_time_ref (date);
705 }
706
707 /**
708 * as_review_get_metadata_item:
709 * @review: a #AsReview
710 * @key: a string
711 *
712 * Gets some metadata from a review object.
713 * It is left for the the plugin to use this method as required, but a
714 * typical use would be to retrieve some secure authentication token.
715 *
716 * Returns: A string value, or %NULL for not found
717 *
718 * Since: 0.6.1
719 **/
720 const gchar *
as_review_get_metadata_item(AsReview * review,const gchar * key)721 as_review_get_metadata_item (AsReview *review, const gchar *key)
722 {
723 AsReviewPrivate *priv = GET_PRIVATE (review);
724 g_return_val_if_fail (AS_IS_REVIEW (review), NULL);
725 g_return_val_if_fail (key != NULL, NULL);
726 return g_hash_table_lookup (priv->metadata, key);
727 }
728
729 /**
730 * as_review_add_metadata:
731 * @review: a #AsReview
732 * @key: a string
733 * @value: a string
734 *
735 * Adds metadata to the review object.
736 * It is left for the the plugin to use this method as required, but a
737 * typical use would be to store some secure authentication token.
738 *
739 * Since: 0.6.1
740 **/
741 void
as_review_add_metadata(AsReview * review,const gchar * key,const gchar * value)742 as_review_add_metadata (AsReview *review, const gchar *key, const gchar *value)
743 {
744 AsReviewPrivate *priv = GET_PRIVATE (review);
745 g_return_if_fail (AS_IS_REVIEW (review));
746 g_hash_table_insert (priv->metadata,
747 as_ref_string_new (key),
748 as_ref_string_new (value));
749 }
750
751 /**
752 * as_review_equal:
753 * @review1: a #AsReview instance.
754 * @review2: a #AsReview instance.
755 *
756 * Checks if two reviews are the same.
757 *
758 * Returns: %TRUE for success
759 *
760 * Since: 0.6.1
761 **/
762 gboolean
as_review_equal(AsReview * review1,AsReview * review2)763 as_review_equal (AsReview *review1, AsReview *review2)
764 {
765 AsReviewPrivate *priv1 = GET_PRIVATE (review1);
766 AsReviewPrivate *priv2 = GET_PRIVATE (review2);
767
768 /* trivial */
769 if (review1 == review2)
770 return TRUE;
771
772 /* check for equality */
773 if (!g_date_time_equal (priv1->date, priv2->date))
774 return FALSE;
775 if (priv1->priority != priv2->priority)
776 return FALSE;
777 if (priv1->rating != priv2->rating)
778 return FALSE;
779 if (g_strcmp0 (priv1->id, priv2->id) != 0)
780 return FALSE;
781 if (g_strcmp0 (priv1->summary, priv2->summary) != 0)
782 return FALSE;
783 if (g_strcmp0 (priv1->description, priv2->description) != 0)
784 return FALSE;
785 if (g_strcmp0 (priv1->locale, priv2->locale) != 0)
786 return FALSE;
787 if (g_strcmp0 (priv1->version, priv2->version) != 0)
788 return FALSE;
789
790 /* success */
791 return TRUE;
792 }
793
794 /**
795 * as_review_node_insert: (skip)
796 * @review: a #AsReview instance.
797 * @parent: the parent #GNode to use..
798 * @ctx: the #AsNodeContext
799 *
800 * Inserts the review into the DOM tree.
801 *
802 * Returns: (transfer none): A populated #GNode
803 *
804 * Since: 0.6.1
805 **/
806 GNode *
as_review_node_insert(AsReview * review,GNode * parent,AsNodeContext * ctx)807 as_review_node_insert (AsReview *review, GNode *parent, AsNodeContext *ctx)
808 {
809 AsReviewPrivate *priv = GET_PRIVATE (review);
810 GNode *n;
811
812 n = as_node_insert (parent, "review", NULL,
813 AS_NODE_INSERT_FLAG_NONE,
814 NULL);
815 if (priv->id != NULL)
816 as_node_add_attribute (n, "id", priv->id);
817 if (priv->priority != 0) {
818 g_autofree gchar *str = g_strdup_printf ("%i", priv->priority);
819 as_node_insert (n, "priority", str,
820 AS_NODE_INSERT_FLAG_NONE,
821 NULL);
822 }
823 if (priv->rating != 0) {
824 g_autofree gchar *str = g_strdup_printf ("%i", priv->rating);
825 as_node_add_attribute (n, "rating", str);
826 }
827 if (priv->date != NULL) {
828 g_autofree gchar *str = g_date_time_format (priv->date, "%F");
829 as_node_add_attribute (n, "date", str);
830 }
831 if (priv->summary != NULL) {
832 as_node_insert (n, "summary", priv->summary,
833 AS_NODE_INSERT_FLAG_NONE,
834 NULL);
835 }
836 if (priv->description != NULL) {
837 as_node_insert (n, "description", priv->description,
838 AS_NODE_INSERT_FLAG_PRE_ESCAPED,
839 NULL);
840 }
841 if (priv->version != NULL) {
842 as_node_insert (n, "version", priv->version,
843 AS_NODE_INSERT_FLAG_NONE,
844 NULL);
845 }
846 if (priv->reviewer_id != NULL) {
847 as_node_insert (n, "reviewer_id", priv->reviewer_id,
848 AS_NODE_INSERT_FLAG_NONE,
849 NULL);
850 }
851 if (priv->reviewer_name != NULL) {
852 as_node_insert (n, "reviewer_name", priv->reviewer_name,
853 AS_NODE_INSERT_FLAG_NONE,
854 NULL);
855 }
856 if (priv->locale != NULL) {
857 as_node_insert (n, "lang", priv->locale,
858 AS_NODE_INSERT_FLAG_NONE,
859 NULL);
860 }
861
862 /* <metadata> */
863 if (g_hash_table_size (priv->metadata) > 0) {
864 AsNode *node_tmp;
865 node_tmp = as_node_insert (n, "metadata", NULL, 0, NULL);
866 as_node_insert_hash (node_tmp, "value", "key", priv->metadata, FALSE);
867 }
868
869 return n;
870 }
871
872 /**
873 * as_review_node_parse:
874 * @review: a #AsReview instance.
875 * @node: a #GNode.
876 * @ctx: a #AsNodeContext.
877 * @error: A #GError or %NULL.
878 *
879 * Populates the object from a DOM node.
880 *
881 * Returns: %TRUE for success
882 *
883 * Since: 0.6.1
884 **/
885 gboolean
as_review_node_parse(AsReview * review,GNode * node,AsNodeContext * ctx,GError ** error)886 as_review_node_parse (AsReview *review, GNode *node,
887 AsNodeContext *ctx, GError **error)
888 {
889 AsReviewPrivate *priv = GET_PRIVATE (review);
890 AsNode *c;
891 const gchar *tmp;
892 gint itmp;
893
894 g_return_val_if_fail (AS_IS_REVIEW (review), FALSE);
895
896 itmp = as_node_get_attribute_as_int (node, "rating");
897 if (itmp != G_MAXINT)
898 as_review_set_rating (review, itmp);
899 tmp = as_node_get_attribute (node, "date");
900 if (tmp != NULL) {
901 g_autoptr(GDateTime) dt = as_utils_iso8601_to_datetime (tmp);
902 if (dt != NULL)
903 as_review_set_date (review, dt);
904 }
905 tmp = as_node_get_attribute (node, "id");
906 if (tmp != NULL)
907 as_review_set_id (review, tmp);
908 for (c = node->children; c != NULL; c = c->next) {
909 if (as_node_get_tag (c) == AS_TAG_SUMMARY) {
910 as_review_set_summary (review, as_node_get_data (c));
911 continue;
912 }
913 if (as_node_get_tag (c) == AS_TAG_PRIORITY) {
914 gint64 prio = g_ascii_strtoll (as_node_get_data (c),
915 NULL, 10);
916 as_review_set_priority (review, (gint) prio);
917 continue;
918 }
919 if (as_node_get_tag (c) == AS_TAG_DESCRIPTION) {
920 g_autoptr(GString) xml = NULL;
921 xml = as_node_to_xml (c->children, AS_NODE_TO_XML_FLAG_INCLUDE_SIBLINGS);
922 as_review_set_description (review, xml->str);
923 continue;
924 }
925 if (as_node_get_tag (c) == AS_TAG_VERSION) {
926 as_review_set_version (review, as_node_get_data (c));
927 continue;
928 }
929 if (as_node_get_tag (c) == AS_TAG_REVIEWER_ID) {
930 as_review_set_reviewer_id (review, as_node_get_data (c));
931 continue;
932 }
933 if (as_node_get_tag (c) == AS_TAG_REVIEWER_NAME) {
934 as_review_set_reviewer_name (review, as_node_get_data (c));
935 continue;
936 }
937 if (as_node_get_tag (c) == AS_TAG_LANG) {
938 as_review_set_locale (review, as_node_get_data (c));
939 continue;
940 }
941 if (as_node_get_tag (c) == AS_TAG_METADATA) {
942 AsNode *c2;
943 for (c2 = c->children; c2 != NULL; c2 = c2->next) {
944 AsRefString *key;
945 AsRefString *value;
946 if (as_node_get_tag (c2) != AS_TAG_VALUE)
947 continue;
948 key = as_node_get_attribute_as_refstr (c2, "key");
949 value = as_node_get_data_as_refstr (c2);
950 if (value == NULL) {
951 g_hash_table_insert (priv->metadata,
952 as_ref_string_ref (key),
953 as_ref_string_new_static (""));
954 } else {
955 g_hash_table_insert (priv->metadata,
956 as_ref_string_ref (key),
957 as_ref_string_ref (value));
958 }
959 }
960 continue;
961 }
962 }
963 return TRUE;
964 }
965
966 /**
967 * as_review_node_parse_dep11:
968 * @review: a #AsReview instance.
969 * @node: a #GNode.
970 * @ctx: a #AsNodeContext.
971 * @error: A #GError or %NULL.
972 *
973 * Populates the object from a DEP-11 node.
974 *
975 * Returns: %TRUE for success
976 *
977 * Since: 0.6.1
978 **/
979 gboolean
as_review_node_parse_dep11(AsReview * im,GNode * node,AsNodeContext * ctx,GError ** error)980 as_review_node_parse_dep11 (AsReview *im, GNode *node,
981 AsNodeContext *ctx, GError **error)
982 {
983 return TRUE;
984 }
985
986 /**
987 * as_review_new:
988 *
989 * Creates a new #AsReview.
990 *
991 * Returns: (transfer full): a #AsReview
992 *
993 * Since: 0.6.1
994 **/
995 AsReview *
as_review_new(void)996 as_review_new (void)
997 {
998 AsReview *review;
999 review = g_object_new (AS_TYPE_REVIEW, NULL);
1000 return AS_REVIEW (review);
1001 }
1002