bukuserver package
bukuserver.filters module
- class bukuserver.filters.BaseFilter(name: str, options: None | Sequence[tuple[str, str | flask_babel.LazyString]] | Callable[[], Sequence[tuple[str, str | flask_babel.LazyString]]] = None, data_type: Literal['daterangepicker', 'datetimepicker', 'datetimerangepicker', 'datepicker', 'select2-tags', 'timepicker', 'timerangepicker', 'uuid'] | str | None = None, key_name: str | None = None)[source]
Bases:
BaseFilter
- class bukuserver.filters.BookmarkBaseFilter(name, operation_text=None, apply_func=None, filter_type=None, options=None, data_type=None)[source]
Bases:
BaseFilter
- class bukuserver.filters.BookmarkBukuFilter(*args, **kwargs)[source]
Bases:
BaseFilter- KEYS = {'all_keywords': 'match all', 'deep': 'deep', 'markers': 'markers', 'regex': 'regex'}
- class bukuserver.filters.BookmarkField(*values)[source]
Bases:
Enum- DESCRIPTION = 4
- ID = 0
- TAGS = 3
- TITLE = 2
- URL = 1
- class bukuserver.filters.BookmarkOrderFilter(field, *args, **kwargs)[source]
Bases:
BaseFilter- DIR_LIST = [('asc', l'natural'), ('desc', l'reversed')]
- FIELDS = ['index', 'url', 'netloc', 'title', 'description', 'tags', '-#', '#']
- class bukuserver.filters.BookmarkTagNumberEqualFilter(*args, **kwargs)[source]
Bases:
BookmarkBaseFilter
- class bukuserver.filters.BookmarkTagNumberGreaterFilter(*args, **kwargs)[source]
Bases:
BookmarkTagNumberEqualFilter
- class bukuserver.filters.BookmarkTagNumberNotEqualFilter(*args, **kwargs)[source]
Bases:
BookmarkTagNumberEqualFilter
- class bukuserver.filters.BookmarkTagNumberSmallerFilter(*args, **kwargs)[source]
Bases:
BookmarkBaseFilter
- class bukuserver.filters.FilterType(*values)[source]
Bases:
Enum- BOTTOM_X = {'func': <function bottom_x_func>, 'text': l'bottom X'}
- CONTAINS = {'func': <function contains_func>, 'text': l'contains'}
- EQUAL = {'func': <function equal_func>, 'text': l'equals'}
- GREATER = {'func': <function greater_func>, 'text': l'greater than'}
- IN_LIST = {'func': <function in_list_func>, 'text': l'in list'}
- NOT_CONTAINS = {'func': <function not_contains_func>, 'text': l'not contains'}
- NOT_EQUAL = {'func': <function not_equal_func>, 'text': l'not equals'}
- NOT_IN_LIST = {'func': <function not_in_list_func>, 'text': l'not in list'}
- SMALLER = {'func': <function smaller_func>, 'text': l'smaller than'}
- TOP_X = {'func': <function top_x_func>, 'text': l'top X'}
- class bukuserver.filters.TagBaseFilter(name, operation_text=None, apply_func=None, filter_type=None, options=None, data_type=None)[source]
Bases:
BaseFilter
bukuserver.forms module
Forms module.
- class bukuserver.forms.ApiBookmarkCreateForm(*args, **kwargs)[source]
Bases:
ApiTagForm- property data_values
- description = <UnboundField(StringField, (), {})>
- fetch = <UnboundField(BooleanField, (), {'filters': [<function <lambda>>]})>
- property has_data
- tags = <UnboundField(ValueList, (), {'item_validators': [<function is_string>, <wtforms.validators.Regexp object>]})>
- title = <UnboundField(StringField, (), {})>
- url = <UnboundField(StringField, (), {'validators': [<wtforms.validators.DataRequired object>]})>
- class bukuserver.forms.ApiBookmarkEditForm(*args, **kwargs)[source]
Bases:
ApiBookmarkCreateForm- property has_data
- url = <UnboundField(StringField, (), {'validators': [<function optional_none>, <wtforms.validators.Length object>]})>
- class bukuserver.forms.ApiBookmarkRangeEditForm(*args, **kwargs)[source]
Bases:
ApiBookmarkEditForm- property data_values
- del_tags = <UnboundField(BooleanField, ('Delete tags list from existing tags',), {'default': False})>
- property tags_in
- class bukuserver.forms.ApiBookmarkSearchForm(*args, **kwargs)[source]
Bases:
Form- all_keywords = <UnboundField(BooleanField, (), {'filters': [<function <lambda>>]})>
- deep = <UnboundField(BooleanField, (), {'filters': [<function <lambda>>]})>
- keywords = <UnboundField(ValueList, (), {'validators': [<wtforms.validators.DataRequired object>], 'item_validators': [<function is_string>]})>
- markers = <UnboundField(BooleanField, (), {'filters': [<function <lambda>>]})>
- order = <UnboundField(ValueList, (), {'item_validators': [<function is_string>]})>
- regex = <UnboundField(BooleanField, (), {'filters': [<function <lambda>>]})>
- class bukuserver.forms.ApiBookmarksReorderForm(*args, **kwargs)[source]
Bases:
Form- order = <UnboundField(ValueList, (), {'validators': [<wtforms.validators.DataRequired object>], 'item_validators': [<function is_string>]})>
- class bukuserver.forms.ApiFetchDataForm(*args, **kwargs)[source]
Bases:
Form- url = <UnboundField(StringField, (), {'validators': [<wtforms.validators.DataRequired object>]})>
- class bukuserver.forms.ApiTagForm(*args, **kwargs)[source]
Bases:
Form- tags = <UnboundField(ValueList, (), {'validators': [<wtforms.validators.DataRequired object>], 'item_validators': [<function is_string>, <wtforms.validators.Regexp object>]})>
- property tags_str
- class bukuserver.forms.BookmarkForm(*args, **kwargs)[source]
Bases:
FlaskForm- description = <UnboundField(TextAreaField, (l'Description',), {})>
- fetch = <UnboundField(HiddenField, (), {'filters': [<class 'bool'>]})>
- tags = <UnboundField(StringField, (l'Tags',), {})>
- title = <UnboundField(StringField, (l'Title',), {})>
- url = <UnboundField(URLField, (l'URL',), {'validators': [<wtforms.validators.InputRequired object>]})>
- class bukuserver.forms.HomeForm(*args, **kwargs)[source]
Bases:
SearchBookmarksForm- keyword = <UnboundField(StringField, (l'Keyword',), {})>
- class bukuserver.forms.SearchBookmarksForm(*args, **kwargs)[source]
Bases:
FlaskForm- all_keywords = <UnboundField(BooleanField, (l'Match all keywords',), {'default': True, 'description': l'Exclude partial matches (with multiple keywords)'})>
- deep = <UnboundField(BooleanField, (l'Deep search',), {'description': l'When unset, only FULL words will be matched.'})>
- keywords = <UnboundField(FieldList, (<UnboundField(StringField, (l'Keywords',), {})>,), {'min_entries': 1})>
- markers = <UnboundField(BooleanField, (l'With markers',), {'default': True, 'description': l'The search string will be split into multiple keywords, each will be applied to a field based on prefix: - keywords starting with '.', '>' or ':' will be searched for in title, description and URL respectively - '#' will be searched for in tags (comma-separated, partial matches; not affected by Deep Search) - '#,' is the same but will match FULL tags only - '*' will be searched for in all fields (this prefix can be omitted in the 1st keyword) Keywords need to be separated by placing spaces before the prefix.'})>
- regex = <UnboundField(BooleanField, (l'Regex',), {'description': l'The keyword(s) are regular expressions (overrides other options).'})>
- class bukuserver.forms.SwapForm(*args, **kwargs)[source]
Bases:
FlaskForm- id1 = <UnboundField(HiddenField, (), {'filters': [<class 'int'>]})>
- id2 = <UnboundField(HiddenField, (), {'filters': [<class 'int'>]})>
- class bukuserver.forms.ValueList(*args, **kwargs)[source]
Bases:
SelectMultipleFieldA form field model for simple value lists, capable of processing regular array data.
bukuserver.response module
- class bukuserver.response.Response(*values)[source]
Bases:
Enum- BOOKMARK_NOT_FOUND = (HTTPStatus.NOT_FOUND, 'Bookmark not found.')
- FAILURE = (HTTPStatus.CONFLICT, 'Failure.')
- INPUT_NOT_VALID = (HTTPStatus.UNPROCESSABLE_ENTITY, 'Input data not valid.')
- INVALID_REQUEST = (HTTPStatus.BAD_REQUEST, 'Ill-formed request.')
- RANGE_NOT_VALID = (HTTPStatus.NOT_FOUND, 'Range not valid.')
- REMOVED = (HTTPStatus.GONE, 'Functionality no longer available.')
- SUCCESS = (HTTPStatus.OK, 'Success.')
- TAG_NOT_FOUND = (HTTPStatus.NOT_FOUND, 'Tag not found.')
- TAG_NOT_VALID = (HTTPStatus.UNPROCESSABLE_ENTITY, 'Invalid tag.')
- static from_flag(flag: bool, *, data: Dict[str, Any] = None, errors: Dict[str, Any] = None)[source]
- property message: str
- property status: int
- property status_code: int
bukuserver.server module
Server module.
bukuserver.views module
views module.
- class bukuserver.views.BookmarkModelView(bukudb: BukuDb, *args, **kwargs)[source]
Bases:
BaseModelView,ApplyFiltersMixin- action_view() Response | Response
Mass-model action view.
- ajax_lookup() Response | Response
- ajax_update() None | tuple[str, int] | str
Edits a single column of a record in list view.
- can_set_page_size = True
Allows to select page size via dropdown list
- can_view_details = True
Setting this to true will enable the details view. This is recommended when there are too many columns to display in the list_view.
- column_filters = ['buku', 'id', 'url', 'title', 'tags', 'order']
Collection of the column filters.
Can contain either field names or instances of
BaseFilterclasses.Example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
- column_formatters = {'entry': <function BookmarkModelView._list_entry>}
Dictionary of list view column formatters.
For example, if you want to show price multiplied by two, you can do something like this:
class MyModelView(BaseModelView): column_formatters = dict(price=lambda v, c, m, p: m.price*2)
or using Jinja2 macro in template:
from flask_admin.model.template import macro class MyModelView(BaseModelView): column_formatters = dict(price=macro('render_price')) # in template {% macro render_price(model, column) %} {{ model.price * 2 }} {% endmacro %}
The Callback function has the prototype:
def formatter(view, context, model, name): # `view` is current administrative view # `context` is instance of jinja2.runtime.Context # `model` is model instance # `name` is property name pass
- column_labels = {'description': l'Description', 'entry': l'Entry', 'id': l'Index', 'tags': l'Tags', 'title': l'Title', 'url': l'URL'}
Dictionary where key is column name and value is string to display.
For example:
class MyModelView(BaseModelView): column_labels = dict(name='Name', last_name='Last Name')
- column_list = ['entry']
Collection of the model field names for the list view. If set to None, will get them from the model.
For example:
class MyModelView(BaseModelView): column_list = ('name', 'last_name', 'email')
(Added in 1.4.0) SQLAlchemy model attributes can be used instead of strings:
class MyModelView(BaseModelView): column_list = ('name', User.last_name)
- When using SQLAlchemy models, you can reference related columns like this::
- class MyModelView(BaseModelView):
column_list = (‘<relationship>.<related column name>’,)
- create_form(obj=None)[source]
Instantiate model creation form and return it.
Override to implement custom behavior.
- create_modal = True
Setting this to true will display the create_view as a modal dialog.
- create_modal_template = 'bukuserver/bookmark_create_modal.html'
Default create modal template
- create_model(form)[source]
Create model from the form.
Returns the model instance if operation succeeded.
Must be implemented in the child class.
- Parameters:
form – Form instance
- create_template = 'bukuserver/bookmark_create.html'
Default create template
- create_view() Response | Response | str
Create model view
- delete_model(model)[source]
Delete model.
Returns True if operation succeeded.
Must be implemented in the child class.
- Parameters:
model – Model instance
- delete_view() Response | Response
Delete model view. Only POST method is allowed.
- details_modal = True
Setting this to true will display the details_view as a modal dialog.
- details_modal_template = 'bukuserver/bookmark_details_modal.html'
Default details modal view template
- details_template = 'bukuserver/bookmark_details.html'
Default details view template
- details_view() Response | Response | str
Details model view
- edit_modal = True
Setting this to true will display the edit_view as a modal dialog.
- edit_modal_template = 'bukuserver/bookmark_edit_modal.html'
Default edit modal template
- edit_template = 'bukuserver/bookmark_edit.html'
Default edit template
- edit_view() Response | Response | str
Edit model view
- export(export_type: str) Response | Response
- extra_css = ['/static/bukuserver/css/bookmark.css', '/static/bukuserver/css/modal.css', '/static/bukuserver/css/list.css']
Extra CSS files to include in the page
- extra_js = ['/static/bukuserver/js/last_page.js', '/static/bukuserver/js/filters_fix.js']
Extra JavaScript files to include in the page
- get_detail_value(context, model, name)[source]
Returns the value to be displayed in the detail view
- Parameters:
context –
jinja2.runtime.Contextmodel – Model instance
name – Field name
- get_list(page, sort_field, sort_desc, _, filters, page_size=None)[source]
Return a tuple of a count of results and a paginated and sorted list of models from the data source.
Must be implemented in the child class.
- Parameters:
page – Page number, 0 based. Can be set to None if it is first page.
sort_field – Sort column name or None.
sort_desc – If set to True, sorting is in descending order.
search – Search query
filters – List of filter tuples. First value in a tuple is a search index, second value is a search value.
page_size – Number of results. Defaults to ModelView’s page_size. Can be overriden to change the page_size limit. Removing the page_size limit requires setting page_size to 0 or False.
- get_one(id)[source]
Return one model by its id.
Must be implemented in the child class.
- Parameters:
id – Model id
- index_view() str
List view
- last_page()
Generic ‘/last_page’ endpoint handler; based on https://github.com/flask-admin/flask-admin/blob/v1.6.0/flask_admin/model/base.py#L1956-L1969
- list_template = 'bukuserver/bookmarks_list.html'
Default list view template
- named_filter_urls = True
Set to True to use human-readable names for filters in URL parameters.
False by default so as to be robust across translations.
Changing this parameter will break any existing URLs that have filters.
- property page_size
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
- property page_size_options
Built-in immutable sequence.
If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable’s items.
If the argument is a tuple, the return value is the same object.
- scaffold_filters(name)[source]
Generate filter object for the given name
- Parameters:
name – Name of the field
- scaffold_form()[source]
Create form.BaseForm inherited class from the model. Must be implemented in the child class.
- scaffold_list_columns()[source]
Return list of the model field names. Must be implemented in the child class.
Expected return format is list of strings of the field names. For example:
['name', 'first_name', 'last_name']
- scaffold_list_form(widget=None, validators=None)[source]
Create form for the index_view using only the columns from self.column_editable_list.
- Parameters:
widget – WTForms widget class. Defaults to XEditableWidget.
validators – form_args dict with only validators {‘name’: {‘validators’: [DataRequired()]}}
Must be implemented in the child class.
- scaffold_sortable_columns()[source]
Returns a dictionary of sortable columns.
from flask-admin docs: If your backend does not support sorting, return None or an empty dictionary.
- update_model(form: BookmarkForm, model: Namespace)[source]
Update model from the form.
Returns True if operation succeeded.
Must be implemented in the child class.
- Parameters:
form – Form instance
model – Model instance
- property url_render_mode
- class bukuserver.views.ColoredData(name, amount, color)
Bases:
tuple- amount
Alias for field number 1
- color
Alias for field number 2
- name
Alias for field number 0
- class bukuserver.views.CustomAdminIndexView(name: str | None = None, category: str | None = None, endpoint: str | None = None, url: str | None = None, template: str = 'admin/index.html', menu_class_name: str | None = None, menu_icon_type: str | None = None, menu_icon_value: str | None = None)[source]
Bases:
AdminIndexView
- class bukuserver.views.StatisticView(bukudb, *args, **kwargs)[source]
Bases:
BaseView- extra_css: list[str] = ['/static/bukuserver/css/modal.css']
Extra CSS files to include in the page
- class bukuserver.views.TagModelView(bukudb, *args, **kwargs)[source]
Bases:
BaseModelView,ApplyFiltersMixin- action_view() Response | Response
Mass-model action view.
- ajax_lookup() Response | Response
- ajax_update() None | tuple[str, int] | str
Edits a single column of a record in list view.
- can_create = False
Is model creation allowed
- can_set_page_size = True
Allows to select page size via dropdown list
- column_filters = ['name', 'usage_count']
Collection of the column filters.
Can contain either field names or instances of
BaseFilterclasses.Example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
- column_formatters = {'name': <function TagModelView._name_formatter>}
Dictionary of list view column formatters.
For example, if you want to show price multiplied by two, you can do something like this:
class MyModelView(BaseModelView): column_formatters = dict(price=lambda v, c, m, p: m.price*2)
or using Jinja2 macro in template:
from flask_admin.model.template import macro class MyModelView(BaseModelView): column_formatters = dict(price=macro('render_price')) # in template {% macro render_price(model, column) %} {{ model.price * 2 }} {% endmacro %}
The Callback function has the prototype:
def formatter(view, context, model, name): # `view` is current administrative view # `context` is instance of jinja2.runtime.Context # `model` is model instance # `name` is property name pass
- column_labels = {'name': l'Name', 'usage_count': l'Usage Count'}
Dictionary where key is column name and value is string to display.
For example:
class MyModelView(BaseModelView): column_labels = dict(name='Name', last_name='Last Name')
- create_model(form)[source]
Create model from the form.
Returns the model instance if operation succeeded.
Must be implemented in the child class.
- Parameters:
form – Form instance
- create_view() Response | Response | str
Create model view
- delete_model(model)[source]
Delete model.
Returns True if operation succeeded.
Must be implemented in the child class.
- Parameters:
model – Model instance
- delete_view() Response | Response
Delete model view. Only POST method is allowed.
- details_view() Response | Response | str
Details model view
- edit_template = 'bukuserver/tag_edit.html'
Default edit template
- edit_view() Response | Response | str
Edit model view
- export(export_type: str) Response | Response
- extra_css = ['/static/bukuserver/css/list.css']
Extra CSS files to include in the page
- extra_js = ['/static/bukuserver/js/last_page.js', '/static/bukuserver/js/filters_fix.js']
Extra JavaScript files to include in the page
- get_list(page: int, sort_field: str, sort_desc: bool, search: Any | None, filters: List[Tuple[int, str, str]], page_size: int = None) Tuple[int, List[SimpleNamespace]][source]
Return a tuple of a count of results and a paginated and sorted list of models from the data source.
Must be implemented in the child class.
- Parameters:
page – Page number, 0 based. Can be set to None if it is first page.
sort_field – Sort column name or None.
sort_desc – If set to True, sorting is in descending order.
search – Search query
filters – List of filter tuples. First value in a tuple is a search index, second value is a search value.
page_size – Number of results. Defaults to ModelView’s page_size. Can be overriden to change the page_size limit. Removing the page_size limit requires setting page_size to 0 or False.
- get_one(id)[source]
Return one model by its id.
Must be implemented in the child class.
- Parameters:
id – Model id
- index_view() str
List view
- last_page()
Generic ‘/last_page’ endpoint handler; based on https://github.com/flask-admin/flask-admin/blob/v1.6.0/flask_admin/model/base.py#L1956-L1969
- list_template = 'bukuserver/tags_list.html'
Default list view template
- named_filter_urls = True
Set to True to use human-readable names for filters in URL parameters.
False by default so as to be robust across translations.
Changing this parameter will break any existing URLs that have filters.
- property page_size
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
- property page_size_options
Built-in immutable sequence.
If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable’s items.
If the argument is a tuple, the return value is the same object.
- scaffold_filters(name)[source]
Generate filter object for the given name
- Parameters:
name – Name of the field
- scaffold_form()[source]
Create form.BaseForm inherited class from the model. Must be implemented in the child class.
- scaffold_list_columns()[source]
Return list of the model field names. Must be implemented in the child class.
Expected return format is list of strings of the field names. For example:
['name', 'first_name', 'last_name']
- scaffold_list_form(widget=None, validators=None)[source]
Create form for the index_view using only the columns from self.column_editable_list.
- Parameters:
widget – WTForms widget class. Defaults to XEditableWidget.
validators – form_args dict with only validators {‘name’: {‘validators’: [DataRequired()]}}
Must be implemented in the child class.
- bukuserver.views.last_page(self)[source]
Generic ‘/last_page’ endpoint handler; based on https://github.com/flask-admin/flask-admin/blob/v1.6.0/flask_admin/model/base.py#L1956-L1969