__package__ = 'archivebox.core' from django import forms from archivebox.misc.util import URL_REGEX from taggit.utils import edit_string_for_tags, parse_tags DEPTH_CHOICES = ( ('0', 'depth = 0 (archive just these URLs)'), ('1', 'depth = 1 (archive these URLs and all URLs one hop away)'), ) from archivebox.hooks import get_plugins def get_plugin_choices(): """Get available extractor plugins from discovered hooks.""" return [(name, name) for name in get_plugins()] class AddLinkForm(forms.Form): url = forms.RegexField(label="URLs (one per line)", regex=URL_REGEX, min_length='6', strip=True, widget=forms.Textarea, required=True) tag = forms.CharField(label="Tags (comma separated tag1,tag2,tag3)", strip=True, required=False) depth = forms.ChoiceField(label="Archive depth", choices=DEPTH_CHOICES, initial='0', widget=forms.RadioSelect(attrs={"class": "depth-selection"})) plugins = forms.MultipleChoiceField( label="Plugins (select at least 1, otherwise all will be used by default)", required=False, widget=forms.SelectMultiple, choices=[], # populated dynamically in __init__ ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['plugins'].choices = get_plugin_choices() # TODO: hook these up to the view and put them # in a collapsible UI section labeled "Advanced" # # exclude_patterns = forms.CharField( # label="Exclude patterns", # min_length='1', # required=False, # initial=URL_DENYLIST, # ) # timeout = forms.IntegerField( # initial=TIMEOUT, # ) # overwrite = forms.BooleanField( # label="Overwrite any existing Snapshots", # initial=False, # ) # index_only = forms.BooleanField( # label="Add URLs to index without Snapshotting", # initial=False, # ) class TagWidgetMixin: def format_value(self, value): if value is not None and not isinstance(value, str): value = edit_string_for_tags(value) return super().format_value(value) class TagWidget(TagWidgetMixin, forms.TextInput): pass class TagField(forms.CharField): widget = TagWidget def clean(self, value): value = super().clean(value) try: return parse_tags(value) except ValueError: raise forms.ValidationError( "Please provide a comma-separated list of tags." ) def has_changed(self, initial_value, data_value): # Always return False if the field is disabled since self.bound_data # always uses the initial value in this case. if self.disabled: return False try: data_value = self.clean(data_value) except forms.ValidationError: pass if initial_value is None: initial_value = [] initial_value = [tag.name for tag in initial_value] initial_value.sort() return initial_value != data_value