forms.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. __package__ = 'archivebox.core'
  2. from django import forms
  3. from ..util import URL_REGEX
  4. from ..parsers import PARSERS
  5. from ..vendor.taggit_utils import edit_string_for_tags, parse_tags
  6. PARSER_CHOICES = [
  7. (parser_key, parser[0])
  8. for parser_key, parser in PARSERS.items()
  9. ]
  10. DEPTH_CHOICES = (
  11. ('0', 'depth = 0 (archive just these URLs)'),
  12. ('1', 'depth = 1 (archive these URLs and all URLs one hop away)'),
  13. )
  14. from ..extractors import get_default_archive_methods
  15. ARCHIVE_METHODS = [
  16. (name, name)
  17. for name, _, _ in get_default_archive_methods()
  18. ]
  19. class AddLinkForm(forms.Form):
  20. url = forms.RegexField(label="URLs (one per line)", regex=URL_REGEX, min_length='6', strip=True, widget=forms.Textarea, required=True)
  21. parser = forms.ChoiceField(label="URLs format", choices=[('auto', 'Auto-detect parser'), *PARSER_CHOICES], initial='auto')
  22. tag = forms.CharField(label="Tags (comma separated tag1,tag2,tag3)", strip=True, required=False)
  23. depth = forms.ChoiceField(label="Archive depth", choices=DEPTH_CHOICES, initial='0', widget=forms.RadioSelect(attrs={"class": "depth-selection"}))
  24. archive_methods = forms.MultipleChoiceField(
  25. label="Archive methods (select at least 1, otherwise all will be used by default)",
  26. required=False,
  27. widget=forms.SelectMultiple,
  28. choices=ARCHIVE_METHODS,
  29. )
  30. # TODO: hook these up to the view and put them
  31. # in a collapsible UI section labeled "Advanced"
  32. #
  33. # exclude_patterns = forms.CharField(
  34. # label="Exclude patterns",
  35. # min_length='1',
  36. # required=False,
  37. # initial=URL_DENYLIST,
  38. # )
  39. # timeout = forms.IntegerField(
  40. # initial=TIMEOUT,
  41. # )
  42. # overwrite = forms.BooleanField(
  43. # label="Overwrite any existing Snapshots",
  44. # initial=False,
  45. # )
  46. # index_only = forms.BooleanField(
  47. # label="Add URLs to index without Snapshotting",
  48. # initial=False,
  49. # )
  50. class TagWidgetMixin:
  51. def format_value(self, value):
  52. if value is not None and not isinstance(value, str):
  53. value = edit_string_for_tags(value)
  54. return super().format_value(value)
  55. class TagWidget(TagWidgetMixin, forms.TextInput):
  56. pass
  57. class TagField(forms.CharField):
  58. widget = TagWidget
  59. def clean(self, value):
  60. value = super().clean(value)
  61. try:
  62. return parse_tags(value)
  63. except ValueError:
  64. raise forms.ValidationError(
  65. "Please provide a comma-separated list of tags."
  66. )
  67. def has_changed(self, initial_value, data_value):
  68. # Always return False if the field is disabled since self.bound_data
  69. # always uses the initial value in this case.
  70. if self.disabled:
  71. return False
  72. try:
  73. data_value = self.clean(data_value)
  74. except forms.ValidationError:
  75. pass
  76. if initial_value is None:
  77. initial_value = []
  78. initial_value = [tag.name for tag in initial_value]
  79. initial_value.sort()
  80. return initial_value != data_value