/
bibtex.rb
286 lines (248 loc) · 8.37 KB
/
bibtex.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# self.author & self.authors should match or one of them should be empty
class Source::Bibtex < Source
before_validation :check_bibtex_type, :check_has_field
#TODO: :update_authors_editor_if_changed? if: Proc.new { |a| a.password.blank? }
has_many :author_roles, class_name: 'Role::SourceAuthor', as: :role_object
has_many :authors, -> { order('roles.position ASC') }, through: :author_roles, source: :person
has_many :editor_roles, class_name: 'Role::SourceEditor', as: :role_object
has_many :editors, -> { order('roles.position ASC') }, through: :editor_roles, source: :person
#region soft_validate calls
soft_validate(:sv_authors_exist)
soft_validate(:sv_year_exists)
soft_validate(:sv_date_exists, set: :recommended_fields)
soft_validate(:sv_contains_a_writer, set: :recommended_fields)
#soft_validate(:no_title, set: :recommended_fields)
soft_validate(:sv_is_article_missing_journal, set: :recommended_fields)
#soft_validate(:sv_URL_exists, set: :recommended_fields)
#endregion
#region constants
# TW required fields (must have one of these fields filled in)
TW_REQ_FIELDS = [
:author,
:editor,
:booktitle,
:title,
:URL,
:journal,
:year,
:stated_year
]
#endregion
def to_bibtex
b = BibTeX::Entry.new(type: self.bibtex_type)
::BIBTEX_FIELDS.each do |f|
if !(f == :bibtex_type) && (!self[f].blank?)
b[f] = self.send(f)
end
end
b
end
def valid_bibtex?
self.to_bibtex.valid?
end
def self.new_from_bibtex(bibtex_entry)
return false if !bibtex_entry.kind_of?(::BibTeX::Entry)
s = Source::Bibtex.new(
bibtex_type: bibtex_entry.type.to_s,
)
bibtex_entry.fields.each do |key, value|
s[key] = value.to_s
end
s
end
def create_related_people
return false if !self.valid? ||
self.new_record? ||
(self.author.blank? && self.editor.blank?) ||
self.roles.count > 0
# if !self.valid
# errors.add(:base, 'invalid source')
# return false
# end
#
# if self.new_record?
# errors.add(:base, 'unsaved source')
# return false
# end
#
# if (self.author.blank? && self.editor.blank?)
# errors.add(:base, 'no people to create')
# return false
# end
#
# if self.roles.count > 0
# errors.add(:base, 'this source already has people attached to it via roles')
# end
bibtex = to_bibtex
bibtex.parse_names
bibtex.names.each do |a|
p = Source::Bibtex.bibtex_author_to_person(a) #p is a TW person
if bibtex.author
self.authors << p if bibtex.author.include?(a)
end
if bibtex.editor
self.editors << p if bibtex.editor.include?(a)
end
end
return true
end
def self.bibtex_author_to_person(bibtex_author)
return false if bibtex_author.class != BibTeX::Name
Person.new(
first_name: bibtex_author.first,
prefix: bibtex_author.prefix,
last_name: bibtex_author.last,
suffix: bibtex_author.suffix)
end
#region has_<attribute>? section
def has_authors? # is there a bibtex author or author roles?
# return true if !(self.author.to_s.strip.length == 0)
return true if !(self.author.blank?)
# author attribute is empty
return false if self.new_record?
# self exists in the db
(self.authors.count > 0) ? (return true) : (return false)
end
def has_editors?
return true if !(self.editor.blank?)
# editor attribute is empty
return false if self.new_record?
# self exists in the db
(self.editors.count > 0) ? (return true) : (return false)
end
def has_writer? # contains either an author or editor
(has_authors?) || (has_editors?) ? true : false
end
def has_date? # is there a year or stated year?
return true if !(self.year.blank?)
return true if !(self.stated_year.blank?)
return false
end
#TODO write has_note?
#endregion
protected
def check_bibtex_type # must have a valid bibtex_type
errors.add(:bibtex_type, 'not a valid bibtex type') if !::VALID_BIBTEX_TYPES.include?(self.bibtex_type)
end
def check_has_field # must have at least one of the required fields (TW_REQ_FIELDS)
valid = false
TW_REQ_FIELDS.each do |i| # for each i in the required fields list
if !self[i].blank?
valid = true
break
end
end
# if i is not nil and not == "", it's validly_published
#if (!self[i].nil?) && (self[i] != '')
# return true
#end
errors.add(:base, 'no core data provided') if !valid
# return false # none of the required fields have a value
end
#region Soft_validation_methods
def sv_authors_exist
if !(has_authors?)
soft_validations.add(:author, 'There is no author associated with this source')
end
end
def sv_contains_a_writer # neither author nor editor
if !has_writer?
soft_validations.add(:author, 'There is neither an author,nor editor associated with this source')
soft_validations.add(:editor, 'There is neither an author,nor editor associated with this source')
end
end
def no_title
if (self.title.blank?)
soft_validations.add(:title, 'There is no title associated with this source')
end
end
def sv_date_exists
if (has_date?)
soft_validations.add(:year, 'There is no year or stated year associated with this source')
soft_validations.add(:stated_year, 'There is no or stated year year associated with this source')
end
end
def sv_year_exists
if !(year.blank?)
soft_validations.add(:year, 'There is no year associated with this source.')
end
end
def no_journal
soft_validations.add(:bibtex_type, 'The source is missing a journal name') if self.journal.blank?
end
def sv_is_article_missing_journal
if (self.bibtex_type == 'article')
if (self.journal.blank?)
soft_validations.add(:bibtex_type, 'The article is missing a journal name')
end
end
end
def no_publisher
if (self.publisher.blank?)
soft_validations.add(:publisher, 'There is no publisher associated with this source')
end
end
def no_booktitle
if (self.booktitle.blank?)
soft_validations.add(:booktitle, 'There is no book title associated with this source')
end
end
def no_included
if self.chapter.blank? && self.pages.blank?
soft_validations.add(:chapter, 'There is neither a chapter nor pages with this source')
soft_validations.add(:pages, 'There is neither a chapter nor pages with this source')
end
end
def missing_required_bibtex_fields
case self.bibtex_type
when 'article' #:article => [:author,:title,:journal,:year]
sv_authors_exist
no_title
article_missing_journal
sv_year_exists
when 'book' #:book => [[:author,:editor],:title,:publisher,:year]
sv_contains_a_writer
self.no_title
self.no_publisher
sv_year_exists
when 'booklet' # :booklet => [:title],
self.no_title
when 'conference' # :conference => [:author,:title,:booktitle,:year],
sv_authors_exist
self.no_title
self.no_booktitle
sv_year_exists
when 'inbook' # :inbook => [[:author,:editor],:title,[:chapter,:pages],:publisher,:year],
sv_contains_a_writer
self.no_title
self.no_included
self.no_publisher
sv_year_exists
when 'incollection' # :incollection => [:author,:title,:booktitle,:publisher,:year],
sv_authors_exist
self.no_title
self.no_booktitle
self.no_publisher
sv_year_exists
when 'inproceedings' # :inproceedings => [:author,:title,:booktitle,:year],
sv_author_exists
no_title
no_booktitle
sv_year_exists
when 'manual' # :manual => [:title],
self.no_title
when 'mastersthesis' # :mastersthesis => [:author,:title,:school,:year],
sv_authors_exist
self.no_title
# :misc => [],
when 'phdthesis' # :phdthesis => [:author,:title,:school,:year],
when 'proceedings' # :proceedings => [:title,:year],
when 'techreport' # :techreport => [:author,:title,:institution,:year],
when 'unpublished' # :unpublished => [:author,:title,:note]
sv_authors_exist
no_title
#check for note
end
end
#endregion
end