scinote-web/app/models/asset.rb
artoscinote 81a9a7225b
Version 1.25.0 (#4087)
* Add initial implementation of inventory stock management [SCI-6402]

* Add stock column type (#3786)

* Add stock column type

* Create new stock column [SCI-6410]

* Small fixed for stock column [SCI-6410]

* Add stock column validations [SCI-6410]

Co-authored-by: Anton <anton@scinote.net>

* Add stock table renders [SCI-6412] (#3787)

Co-authored-by: Anton <anton@scinote.net>

* Implemented stock management modal [SCI-6417] (#3788)

* Implement inventory stock management modal [SCI-6417]

* Add generalized validation mechanic, some bugfixes [SCI-6417]

* Fix permission check and method name in RepositoryStockValue [SCI-6417]

* Add stock and consumption to assigned items section [SCI-6434] (#3793)

* Added UPDATE_STOCK_CONSUMPTION to MyModule permissons [SCI-6418] (#3781)

* Fix invalid return in reports jobs [SCI-6409] (#3777)

* Added UPDATE_STOCK_CONSUMPTION to MyModule permissons [SCI-6418]

* Add current/new amount section to stock [SCI-6416] (#3791)

Co-authored-by: Anton <anton@scinote.net>

* Task stock consumption modal[SCI-6444][SCI-6445] (#3798)

Add main logic for consumption on task [SCI-6444]

Co-authored-by: Anton <anton@scinote.net>

* Add stock management columns to snapshots [SCI-6448]

* Handle stock management in full table views [SCI-6440]

* Implement stock management activities [SCI-6452] (#3810)

* Implement stock management activities [SCI-6452]

* PR code fixes [SCI-6452]

* Implement import for repository stock values [SCI-6461] (#3818)

* Add permissions checking to assigned items view on tasks [SCI-6435] (#3801)

* Add front-end validation for comments field [SCI-6464] (#3829)

Co-authored-by: Anton <anton@scinote.net>

* Add stock consumption to pdf and docx [SCI-6460] (#3816)

Co-authored-by: Anton <anton@scinote.net>

* Add support of repository snapshots to assigned items section [SCI-6439] (#3828)

* Change subject of Repository (#3838)

* Fixed full view assigned items modal stock consumption (#3846)

* Implement repository snapshots displaying on assigned items full view modal [SCI-6442] (#3862)

* Implement low stock threshold column [SCI-6555] (#3907)

* Stock column fixes [SCI-6455] (#3878)

* Fix issues with stock column management [SCI-6455]

* Refactor stock column in datatables [SCI-6455]

* Fix tests [SCI-6486] (#3913)

* Fix tests [SCI-6486]

* Fix rspec tests [SCI-6486]

Co-authored-by: Anton <anton@scinote.net>

* Implement basic logic for Date/DateTime/Stock reminders [SCI-6554] (#3911)

* Implement basic logic for Date/DateTime/Stock reminders [SCI-6554]

* Implement bell icon [SCI-6500]

* Refactor reminder cells scope [SCI-6554]

* Add red dot for date/datetime reminder [SCI-6499] (#3924)

Co-authored-by: Anton <anton@scinote.net>

* Add reminders to stock modal [SCI-6557] (#3917)

Co-authored-by: Anton <anton@scinote.net>

* Add flyout for repository reminders [SCI-6501] (#3926)

Co-authored-by: Anton <anton@scinote.net>

* Fix moving experiment [SCI-6602] (#3927)

* Update Rails to 6.1.4.7 [SCI-6615] (#3928)

* Task inventory activity for assigned item consumption [SCI-6453] (#3830)

* Add task inventory activity [SCI-6453]

* Apply user's time zone in advanced filters for time data type [SCI-6585] (#3930)

* Bump version to 1.24.2

* Implement hidden repository cell reminders [SCI-6504] (#3933)

* Low stock flyout reminders [SCI-6502] (#3932)

* Display low stock flyout reminder [SCI-6502]

* Display low stock flyout reminder [SCI-6502]

* Adapt showing stock reminders for every bell icon click [SCI-6502]

* Correct hound error [SCI-6502]

* Fix event registration for fetching reminder data [SCI-6502]

* Fix event registration for fetching reminder data [SCI-6502]

* Fix hound [SCI-6502]

* Remove not needed line [SCI-6502]

* Add reminder template [SCI-6502]

* Add clearing messages [SCI-6502]

* Displaying low stock warning [SCI-6497] (#3912)

* Low stock warning [SCI-6497

* Fix some bugs [SCI-6497]

* Fix to long line [SCI-6497]

* Clean not needed information in renderes [SCI-6497]

* Icon bell reminder for an assigned item on the task [SCI-6506] (#3929)

* Add bell icon on assigned task [SCI-6506]

* Add flyout and improve quering [SCI-6506]

* Refactor repository toolbar [SCI-6545] (#3943)

Co-authored-by: Anton <anton@scinote.net>

* Add datetime reminders to columns modal [SCI-6556] (#3934)

Co-authored-by: Anton <anton@scinote.net>

* Hide reminders for archived repositories [SCI-6609] (#3941)

* Hide reminders for archived repositories [SCI-6609]

* Always pass repository in datatable helper [SCI-6609]

* Handle locked stock consumption state [SCI-6608] (#3942)

* Change env variable name for s3 bucket region [SCI-6603] (#3944)

* Add last_transition_error column to tasks [SCI-6610] (#3949)

* Add microtransactions to stock consumptions [SCI-6626] (#3948)

Co-authored-by: Anton <anton@scinote.net>

* Date remidner flyout [SCI-6503] (#3937)

* Implement date reminder flyout [SCI-6503]

* Show only days left for date reminder [SCI-6503]

* Pluralize day in reminders [SCI-6503]

* Create partials for different reminders [SCI-6503]

* Unify css for reminder [SCI-6503]

* Add micro interactions for stock modal [SCI-6625] (#3947)

Co-authored-by: Anton <anton@scinote.net>

* Hide options to add New Tags for users without permissions on Task level [SCI-6573] (#3945)

* Bump lodash-es from 4.17.15 to 4.17.21 (#3939)

Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21)

---
updated-dependencies:
- dependency-name: lodash-es
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Implement clearing hidden repository reminders [SCI-6507] (#3936)

* Add stock filters [SCI-6547] (#3938)

Co-authored-by: Anton <anton@scinote.net>

* Fix assign view for task repository [SCI-6648] (#3954)

Co-authored-by: Anton <anton@scinote.net>

* Add micro-interactions to reminders flyout [SCI-6627] (#3951)

Co-authored-by: Anton <anton@scinote.net>

* Improve error reporting in task status transition [SCI-6611] (#3952)

* Add ordering to global search results [SCI-6639] (#3960)

* Fix multiple stock bugs [SCI-6651] (#3959)

Co-authored-by: Anton <anton@scinote.net>

* Fix large previews for csv files [SCI-6619] (#3961)

* Add alias to cell sort query, to prevent join conflicts [SCI-6649] (#3953)

* Add alias to cell sort query, to prevent join conflicts [SCI-6649]

* Added value_type to join condition to make use of DB index [SCI-6649]

* Update front end validation for columns managment [SCI-6657] (#3962)

Co-authored-by: Anton <anton@scinote.net>

* Print protocol smart annotation and table improvements [SCI-6566] (#3925)

* Improve table printing in the print menu [SCI-6566]

* Open smart annotation in new tab for print view [SCI-6566]

* Unify naming of same parameter [SCI-6566]

* Fix typo [SCI-6566]

* Fix hound errors [SCI-6566]

* Add stock management toggling [SCI-6653] (#3967)

Co-authored-by: Anton <anton@scinote.net>

* Fix caching of an experiment card dropdown [SCI-6606] (#3963)

* Add stock consumption permission to user roles [SCI-6665] (#3966)

* Show archive icon only on archived projects in the header [SCI-6617] (#3965)

* Fix assigned items fullview modal [SCI-6664] (#3968)

* Implement hide all repository reminders button [SCI-6505] (#3940)

* Viewer role does not see any tasks in archived project [SCI-6616] (#3958)

* Fix viewer role not see any tasks in archived project [SCI-6616]

* Fix rollback for add read archive permission migration [SCI-6616]

* Stock modal bugs [SCI-6667] (#3970)

Co-authored-by: Anton <anton@scinote.net>

* Always use Tika text extractor in server mode [SCI-6658] (#3957)

* Implement stock consumption via the API [SCI-6642] (#3964)

* Implement stock consumption via the API [SCI-6642]

* Remove unnecessary attribute from InventoryItemSerializer [SCI-6642]

* Amend permission check, add nested transaction support to consume_stock method [SCI-6642]

* Toolbar fixes [SCI-6670] (#3973)

Co-authored-by: Anton <anton@scinote.net>

* Make stock column work properly with different orders [SCI-6677] (#3974)

* Fix filters loading for stock filter [SCI-6687] (#3975)

Co-authored-by: Anton <anton@scinote.net>

* Hide reminders and disable stock consumption for archived items [SCI-6689] (#3978)

* Fix red dot for datetime columns [SCI-6684] (#3977)

Co-authored-by: Anton <anton@scinote.net>

* Fix saving of inventory date time reminders saving [SCI-6672] (#3976)

* Bump puma from 5.6.2 to 5.6.4 (#3972)

Bumps [puma](https://github.com/puma/puma) from 5.6.2 to 5.6.4.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/master/History.md)
- [Commits](https://github.com/puma/puma/compare/v5.6.2...v5.6.4)

---
updated-dependencies:
- dependency-name: puma
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Don't load reminders if the stock feature is disabled [SCI-6673] (#3981)

* Don't load reminders if the stock feature is disabled [SCI-6673]

* Don't load reminders if the stock feature is disabled [SCI-6673]

* Unify stock management enabled check [6673]

* Update repository card view for stock [SCI-6685] (#3982)

Co-authored-by: Anton <anton@scinote.net>

* Disable stock managememnt for all tables in my module context [SCI-6692] (#3983)

* Implement failed snapshot pop-up on task screen [SCI-6612] (#3950)

* Implement failed snapshot pop-up on task screen [SCI-6612]

* Copy change [SCI-6612]

* Proper handling of snapshot transition error [SCI-6612]

* Move modal auto open logic to JS file [SCI-6612]

* Remove unnecessary .html_safe [SCI-6612]

* Fix assigning and consuming items [SCI-6686] (#3985)

* Repository toolbar CSS fixes [SCI-6676] (#3984)

Co-authored-by: Anton <anton@scinote.net>

* Add basic validation to reminder value to prevent integer overflow errors [SCI-6693] (#3986)

* Fix reminder dropdown on task screen [SCI-6678] (#3987)

Co-authored-by: Anton <anton@scinote.net>

* Fix inventory sorting with date time reminders [SCI-6683] (#3980)

* Fix css stock modal [SCI-6675] (#3989)

Co-authored-by: Anton <anton@scinote.net>

* Stock column management UX/UI fixes [SCI-6674] (#3979)

* Fix red dot for dates in repository [SCI-6696] (#3991)

Co-authored-by: Anton <anton@scinote.net>

* Added styling for failed snapshots in sidebar [SCI-6636] (#3990)

* Added styling for failed snapshots in sidebar [SCI-6636]

* Simplify markup for failed icon [SCI-6636]

* Turn off autocomplete for stock amount/reminder [SCI-6694] (#3988)

* Override error styling in stock column management [SCI-6674] (#3995)

* Fix repository full view tables without stock management [SCI-6703] (#3994)

* Add pagination to projects list [SCI-6655]

* Add reminder preset to date(time) reminders [SCI-6693] (#3996)

* Fix color on consumption link [SCI-6686] (#3992)

* Fix sorting by date time columns in inventories [SCI-6683] (#4002)

* Improve loading of the dashboard [SCI-6618] (#4001)

* Stock modal UX fixes [SCI-6714] (#3998)

Co-authored-by: Anton <anton@scinote.net>

* Fix css for stotck modal [SCI-6698] (#3999)

Co-authored-by: Anton <anton@scinote.net>

* API: add endpoint for updating of stock [SCI-6549] (#3955)

* Add test for Stock repository cell [SCI-6549]

* Create and update stock inventory cell [SCI-6549]

* Fix hound errors [SCI-6549]

* Fix ledger recording [SCI-6549]

* Fix api endpoint [SCI-6549]

* Fix hound [SCI-6549]

* Fix collapsing of assigned items tables [SCI-6705] (#4000)

* API: add endpoint for creating stock column [SCI-6550] (#3956)

* Add test for repositoty stock column api [SCI-6550]

* Create and update stock column [SCI-6550]

* Change stock unit [SCI-6550]

* Fix hound [SCI-6550]

* Fix on delete [SCI-6550]

* Fix houd [SCI-6550]

* Removed autofocus clear on open reminder flyout [SCI-6690] (#4003)

* Removed clear autofocus on open reminder flyout [SCI-6690]

* Fix hound [SCI-6690]

* Adding/changing stock consumption [SCI-6708] (#4005)

* Adding/changing stock consumption [SCI-6708]

* Fix hound [SCI-6708]

* Remove date red dots for snapshots [SCI-6715] (#4004)

Co-authored-by: Anton <anton@scinote.net>

* Add snapshot error message below task status [SCI-6614] (#4009)

* Add repository snapshot error modal [SCI-6613] (#3993)

* Bump nokogiri from 1.13.3 to 1.13.4 (#4008)

Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.3 to 1.13.4.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/v1.13.4/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.3...v1.13.4)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add pagination for experiments [SCI-6656]

* Fix sorting by time and time range columns [SCI-6683] (#4011)

* Bump moment from 2.24.0 to 2.29.2 (#4006)

Bumps [moment](https://github.com/moment/moment) from 2.24.0 to 2.29.2.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.24.0...2.29.2)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Align items in assigned item section [SCI-6707] (#4007)

* Add locking and unique index to repository row assigning [SCI-6591] (#3921)

* tmp (#3935)

* Revert "tmp (#3935)" (#4014)

This reverts commit 043086d55f.

* Move cursor to end of value when focusing consumption amount [SCI-6727] (#4013)

* Fix removing stock reminder threshold [SCI-6724] (#4010)

* Stock small ux fixes [SCI-6714] (#4015)

Co-authored-by: Anton <anton@scinote.net>

* Add aibility to delete stock column [SCI-6723] (#4017)

Co-authored-by: Anton <anton@scinote.net>

* Fix red dot for date reminders [SCI-6696] (#4016)

Co-authored-by: Anton <anton@scinote.net>

* Change the way setting stock works [SCI-6730] (#4018)

* Fix error modal opening on successful snapshot [SCI-6726] (#4019)

* Refactor and fix display of stock warnings and stock consumption [SCI-6734] (#4021)

* Refactor and fix how stock consumption is displayed [SCI-6734]

* Refactor and fix display of stock warnings [SCI-6734]

* Fix stock consumption in reports [SCI-6735]

* Fix markup

* Focus authenticator code field [SCI-6716] (#4022)

* Hide reminders settings and red dots if stock is disabled [SCI-6673] (#4024)

* Fix decimals in stock consumption modal [SCI-6732]

* Add edit title for stock consumption modal [SCI-6731]

* Highlight negative stock in modal with red [SCI-6729]

* Stock management test [SCI-6420] (#3946)

* Initial test for stock management

* Repository stock values adding [does not work] SCI-6420

* Fix typos SCI-6420

* Fix test [SCI-6420]

* Test changes [SCI-6402]

* Remove locking test [SCI-6420]

* Remove lock [SCI-6420]

* Remove serializer [SCI-6420]

* Fix stock test and add ledger creation on consume [SCI-6420]

* Fix inviting users to team [SCI-6725] (#4026)

* Improve stock ledger records creation [SCI-6419]

* Fix stock modal add/remove value preset value [SCI-6740]

* API GET repository stock column output fix [SCI-6550] (#4030)

* Add include stock unit items to Stock column get [SCI-6550]

* Fix stock column test [SCI-6550]

* Fix hound [SCI-6550]

* Move list-type column includes to param, unify naming [SCI-6738] (#4036)

* Add default includes for inventory columns with lists [SCI-6738]

* Move list-type column includes to param, unify naming [SCI-6738]

* Fix snapshot consumption display [SCI-6734] (#4035)

* Fix decimal render function [SCI-6742] (#4037)

Co-authored-by: Anton <anton@scinote.net>

* Add comment to repository stock activities [SCI-6746]

* Fix default stock column default units selection [SCI-6744]

* Add negative validation for stock [SCI-6743]

* Highlight negative value in consumption modal [SCI-6741]

* Fix snapshot creation with stock consumption [SCI-6762]

* Update stock value without reloading the table [SCI-6745] (#4041)

* Allow tag creation on task level if you have permission [SCI-6573] (#4031)

* Enable team normal user to edit repository files [SCI-6765] (#4049)

* Add negative validation for treshold [SCI-6743]

* Copy fix [SCI-6762] (#4048)

* Add bell icon for negative stock [SCI-6770]

* Fix formatting of stock consumption on tasks [SCI-6737] (#4050)

* Fix duplicated inventories on tasks for export all [SCI-6776]

* Stock / stock consumption display fixes [SCI-6771] (#4054)

* Fix blank stock consumption representation in reports [SCI-6769]

* Upgrade Rails to 6.1.5.1

* Show last page message only after second page [SCI-6761]

* Small CSS fixes for repository [SCI-6767]

* Added validations for date(time) column reminder [SCI-6775] (#4063)

* Upgrade Ruby to 2.7.6

* Open repository on print view [SCI-6566] (#4055)

* Fix saving of new date time columns with reminders [SCI-6774] (#4068)

* Improve input field for adding new team [SCI-6155]

* Allow deleteion of stock columns when stock management is disabled [SCI-6800]

* Update default label template [SCI-6763] (#4064)

* Stock editing and reminder fixes [SCI-6803] (#4078)

* Fix stock editing after adding new value [SCI-6803]

* Don't load reminders for snapshots [SCI-6803]

* Improve loading time of canvas view/edit [SCI-6797]

* Fix stock consumption rounding [SCI-6807]

* Fix displaying of stock consumption units [SCI-6795]

* Fix task dropdown actions [SCI-6817]

* Fix archived tasks view [SCI-6822]

* Fix display of repository snapshot with stock consumption [SCI-6824]

* Fix duplicated counters on task card [SCI-6825]

* Bump version to 1.25.0

Co-authored-by: Oleksii Kriuchykhin <okriuchykhin@biosistemika.com>
Co-authored-by: aignatov-bio <47317017+aignatov-bio@users.noreply.github.com>
Co-authored-by: Anton <anton@scinote.net>
Co-authored-by: ajugo <andrej.jugovic7@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-11 10:39:51 +02:00

517 lines
14 KiB
Ruby

# frozen_string_literal: true
class Asset < ApplicationRecord
include SearchableModel
include DatabaseHelper
include Encryptor
include WopiUtil
include ActiveStorageFileUtil
include ActiveStorageConcerns
require 'tempfile'
# Lock duration set to 30 minutes
LOCK_DURATION = 60 * 30
enum view_mode: { thumbnail: 0, list: 1, inline: 2 }
# ActiveStorage configuration
has_one_attached :file
has_one_attached :file_pdf_preview
# Asset validation
# This could cause some problems if you create empty asset and want to
# assign it to result
validate :step_or_result_or_repository_asset_value
validate :wopi_filename_valid, on: :wopi_file_creation
validate :check_file_size, on: :on_api_upload
belongs_to :created_by,
foreign_key: 'created_by_id',
class_name: 'User',
optional: true
belongs_to :last_modified_by,
foreign_key: 'last_modified_by_id',
class_name: 'User',
optional: true
belongs_to :team, optional: true
has_one :step_asset, inverse_of: :asset, dependent: :destroy
has_one :step, through: :step_asset, touch: true, dependent: :nullify
has_one :result_asset, inverse_of: :asset, dependent: :destroy
has_one :result, through: :result_asset, touch: true, dependent: :nullify
has_one :repository_asset_value, inverse_of: :asset, dependent: :destroy
has_one :repository_cell, through: :repository_asset_value,
dependent: :nullify
has_many :report_elements, inverse_of: :asset, dependent: :destroy
has_one :asset_text_datum, inverse_of: :asset, dependent: :destroy
scope :sort_assets, lambda { |sort_value = 'new'|
sort = case sort_value
when 'old' then { created_at: :asc }
when 'atoz' then { 'active_storage_blobs.filename': :asc }
when 'ztoa' then { 'active_storage_blobs.filename': :desc }
else { created_at: :desc }
end
joins(file_attachment: :blob).order(sort)
}
attr_accessor :file_content, :file_info, :in_template
before_save :reset_file_processing, if: -> { file.new_record? }
def self.search(
user,
include_archived,
query = nil,
page = 1,
_current_team = nil,
options = {}
)
teams = user.teams.select(:id)
assets_in_steps = Asset.joins(:step).where(
'steps.id IN (?)',
Step.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.select(:id)
).pluck(:id)
assets_in_results = Asset.joins(:result).where(
'results.id IN (?)',
Result.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.select(:id)
).pluck(:id)
assets_in_inventories = Asset.joins(
repository_cell: { repository_column: :repository }
).where('repositories.team_id IN (?)', teams).pluck(:id)
assets =
Asset.distinct
.where('assets.id IN (?) OR assets.id IN (?) OR assets.id IN (?)',
assets_in_steps, assets_in_results, assets_in_inventories)
new_query = Asset.left_outer_joins(:asset_text_datum)
.joins(file_attachment: :blob)
.from(assets, 'assets')
a_query = s_query = ''
if options[:whole_word].to_s == 'true' ||
options[:whole_phrase].to_s == 'true'
like = options[:match_case].to_s == 'true' ? '~' : '~*'
s_query = query.gsub(/[!()&|:]/, ' ')
.strip
.split(/\s+/)
.map { |t| t + ':*' }
if options[:whole_word].to_s == 'true'
a_query = query.split
.map { |a| Regexp.escape(a) }
.join('|')
s_query = s_query.join('|')
else
a_query = Regexp.escape(query)
s_query = s_query.join('&')
end
a_query = '\\y(' + a_query + ')\\y'
s_query = s_query.tr('\'', '"')
new_query = new_query.where(
"(active_storage_blobs.filename #{like} ? " \
"OR asset_text_data.data_vector @@ to_tsquery(?))",
a_query,
s_query
)
else
like = options[:match_case].to_s == 'true' ? 'LIKE' : 'ILIKE'
a_query = query.split.map { |a| "%#{sanitize_sql_like(a)}%" }
# Trim whitespace and replace it with OR character. Make prefixed
# wildcard search term and escape special characters.
# For example, search term 'demo project' is transformed to
# 'demo:*|project:*' which makes word inclusive search with postfix
# wildcard.
s_query = query.gsub(/[!()&|:]/, ' ')
.strip
.split(/\s+/)
.map { |t| t + ':*' }
.join('|')
.tr('\'', '"')
new_query = new_query.where(
"(active_storage_blobs.filename #{like} ANY (array[?]) " \
"OR asset_text_data.data_vector @@ to_tsquery(?))",
a_query,
s_query
)
end
# Show all results if needed
if page != Constants::SEARCH_NO_LIMIT
new_query = new_query.select('assets.*, asset_text_data.data AS data')
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
Asset.select(
"assets_search.*, ts_headline(assets_search.data, to_tsquery('" +
sanitize_sql_for_conditions(s_query) +
"'), 'StartSel=<mark>, StopSel=</mark>') AS headline"
).from(new_query, 'assets_search')
else
new_query
end
end
def blob
file&.blob
end
def previewable?
return false unless file.attached?
previewable_document?(blob) || previewable_image?
end
def medium_preview
file.representation(resize_to_limit: Constants::MEDIUM_PIC_FORMAT)
end
def large_preview
file.representation(resize_to_limit: Constants::LARGE_PIC_FORMAT)
end
def file_name
return '' unless file.attached?
file.blob&.filename&.sanitized
end
def render_file_name
if file.attached? && file.metadata['asset_type']
file.metadata['name']
else
file_name
end
end
def file_size
return 0 unless file.attached?
file.blob&.byte_size
end
def content_type
return '' unless file.attached?
file&.blob&.content_type
end
def duplicate
new_asset = dup
return unless new_asset.save
duplicate_file(new_asset)
new_asset
end
def duplicate_file(to_asset)
return unless file.attached?
raise ArgumentError, 'Destination asset should be persisted first!' unless to_asset.persisted?
file.blob.open do |tmp_file|
to_blob = ActiveStorage::Blob.create_and_upload!(io: tmp_file, filename: blob.filename, metadata: blob.metadata)
to_asset.file.attach(to_blob)
end
to_asset.post_process_file(to_asset.team)
end
def image?
content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
end
def text?
Constants::TEXT_EXTRACT_FILE_TYPES.any? do |v|
file&.blob&.content_type&.start_with? v
end
end
def marvinjs?
file.metadata[:asset_type] == 'marvinjs'
end
def bio_eddie?
file.metadata[:asset_type] == 'bio_eddie' || File.extname(file_name) == '.helm'
end
def pdf_preview_ready?
return false if pdf_preview_processing
return true if file_pdf_preview.attached?
PdfPreviewJob.perform_later(id)
ActiveRecord::Base.no_touching { update(pdf_preview_processing: true) }
false
end
def pdf?
content_type == 'application/pdf'
end
def pdf_previewable?
pdf? || (previewable_document?(blob) && Rails.application.config.x.enable_pdf_previews)
end
def post_process_file(team = nil)
# Extract asset text if it's of correct type
if text?
Rails.logger.info "Asset #{id}: Creating extract text job"
# The extract_asset_text also includes
# estimated size calculation
Asset.delay(queue: :assets).extract_asset_text_delayed(id, in_template)
elsif marvinjs?
extract_asset_text
else
# Update asset's estimated size immediately
update_estimated_size(team)
end
if Rails.application.config.x.enable_pdf_previews && previewable_document?(blob)
PdfPreviewJob.perform_later(id)
ActiveRecord::Base.no_touching { update(pdf_preview_processing: true) }
end
end
def self.extract_asset_text_delayed(asset_id, in_template = false)
asset = find_by(id: asset_id)
return unless asset.present? && asset.file.attached?
asset.extract_asset_text(in_template)
end
def extract_asset_text(in_template = false)
self.in_template = in_template
if marvinjs?
mjs_doc = Nokogiri::XML(file.metadata[:description])
mjs_doc.remove_namespaces!
text_data = mjs_doc.search("//Field[@name='text']").collect(&:text).join(' ')
else
# Start Tika as a server
Yomu.server(:text)
begin
blob.open do |tmp_file|
text_data = Yomu.new(tmp_file.path).text
end
ensure
Yomu.kill_server!
end
end
if asset_text_datum.present?
# Update existing text datum if it exists
asset_text_datum.update(data: text_data)
else
# Create new text datum
AssetTextDatum.create(data: text_data, asset: self)
end
Rails.logger.info "Asset #{id}: Asset file successfully extracted"
# Finally, update asset's estimated size to include
# the data vector
update_estimated_size(team)
rescue StandardError => e
Rails.logger.fatal(
"Asset #{id}: Error extracting contents from asset "\
"file #{file.blob.key}: #{e.message}"
)
end
# If team is provided, its space_taken
# is updated as well
def update_estimated_size(team = nil)
return if file_size.blank? || in_template
es = file_size
if asset_text_datum.present? && asset_text_datum.persisted?
asset_text_datum.reload
es += get_octet_length_record(asset_text_datum, :data)
es += get_octet_length_record(asset_text_datum, :data_vector)
end
es *= Constants::ASSET_ESTIMATED_SIZE_FACTOR
update(estimated_size: es)
Rails.logger.info "Asset #{id}: Estimated size successfully calculated"
# Finally, update team's space
if team.present?
team.take_space(es)
team.save
end
end
def can_perform_action(action)
if ENV['WOPI_ENABLED'] == 'true'
file_ext = file_name.split('.').last
if file_ext == 'wopitest' &&
(!ENV['WOPI_TEST_ENABLED'] || ENV['WOPI_TEST_ENABLED'] == 'false')
return false
end
action = get_action(file_ext, action)
return false if action.nil?
true
else
false
end
end
def get_action_url(user, action, with_tokens = true)
file_ext = file_name.split('.').last
action = get_action(file_ext, action)
if !action.nil?
action_url = action[:urlsrc]
if ENV['WOPI_BUSINESS_USERS'] && ENV['WOPI_BUSINESS_USERS'] == 'true'
action_url = action_url.gsub(/<IsLicensedUser=BUSINESS_USER&>/,
'IsLicensedUser=1&')
action_url = action_url.gsub(/<IsLicensedUser=BUSINESS_USER>/,
'IsLicensedUser=1')
else
action_url = action_url.gsub(/<IsLicensedUser=BUSINESS_USER&>/,
'IsLicensedUser=0&')
action_url = action_url.gsub(/<IsLicensedUser=BUSINESS_USER>/,
'IsLicensedUser=0')
end
action_url = action_url.gsub(/<.*?=.*?>/, '')
rest_url = Rails.application.routes.url_helpers.wopi_rest_endpoint_url(
host: ENV['WOPI_ENDPOINT_URL'],
id: id
)
action_url += "WOPISrc=#{rest_url}"
if with_tokens
token = user.get_wopi_token
action_url + "&access_token=#{token.token}"\
"&access_token_ttl=#{(token.ttl * 1000)}"
else
action_url
end
else
return nil
end
end
def favicon_url(action)
file_ext = file_name.split('.').last
action = get_action(file_ext, action)
action[:icon] if action[:icon]
end
# locked?, lock_asset and refresh_lock rely on the asset
# being locked in the database to prevent race conditions
def locked?
unlock_expired
!lock.nil?
end
def lock_asset(lock_string)
self.lock = lock_string
self.lock_ttl = Time.now.to_i + LOCK_DURATION
save!
end
def refresh_lock
self.lock_ttl = Time.now.to_i + LOCK_DURATION
save!
end
def unlock
self.lock = nil
self.lock_ttl = nil
save!
end
def unlock_expired
with_lock do
if !lock_ttl.nil? && lock_ttl < Time.now.to_i
self.lock = nil
self.lock_ttl = nil
save!
end
end
end
def update_contents(new_file)
file.attach(io: new_file, filename: file_name)
self.version = version.nil? ? 1 : version + 1
save
end
def editable_image?
!locked? && %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES_EDITABLE)}} =~ file.content_type
end
def generate_base64(style)
return convert_variant_to_base64(medium_preview) if style == :medium
end
def my_module
(result || step)&.my_module
end
private
def tempdir
Rails.root.join('tmp')
end
def previewable_image?
file.blob&.content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
end
def step_or_result_or_repository_asset_value
# We must allow both step and result to be blank because of GUI
# (even though it's not really a "valid" asset)
if step.present? && result.present? ||
step.present? && repository_asset_value.present? ||
result.present? && repository_asset_value.present?
errors.add(
:base,
'Asset can only be result or step or repository cell, not ever.'
)
end
end
def wopi_filename_valid
# Check that filename without extension is not blank
if file_name[0..-6].blank?
errors.add(
:file,
I18n.t('general.text.not_blank')
)
end
# Check maximum filename length
if file_name.length > Constants::FILENAME_MAX_LENGTH
errors.add(
:file,
I18n.t(
'general.file.file_name_too_long',
limit: Constants::FILENAME_MAX_LENGTH
)
)
end
end
def check_file_size
if file.attached?
if file.blob.byte_size > Rails.application.config.x.file_max_size_mb.megabytes
errors.add(:file, I18n.t('activerecord.errors.models.asset.attributes.file.too_big'))
end
end
end
def reset_file_processing
self.file_processing = false
end
end