Guest User

Untitled

a guest
Apr 11th, 2018
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.10 KB | None | 0 0
  1. # My first Ruby program
  2. # Author:: Zhybul Kiryl (mailto:lucifer4u@gmail.com)
  3. # Copyright:: Copyright (c) 2007 Zhybul Kiryl
  4. # Revision:: 4
  5. # Created:: 25.08.2007 22:47 (GMT+2)
  6.  
  7.  
  8. # Ideal module have set of tools to create validable structures which can be
  9. # easily transformed to other data types. Once the structure definition and
  10. # transformation tool was created - it can be used anytime with any data which
  11. # passed Ideal Structure validator
  12. module Ideal
  13. # Element is a helper for XML generation
  14. class Element
  15.  
  16. @@open_tag_prefix = '<'
  17.  
  18. @@open_tag_postfix = '>'
  19.  
  20. @@close_tag_prefix = '</'
  21.  
  22. @@close_tag_postfix = '>'
  23.  
  24. def initialize(name)
  25. @name = name
  26. @attributes = {}
  27. @content = ''
  28. end
  29.  
  30. def attributes= (attributes)
  31. attributes.each do |key, value|
  32. @attributes[key] = value
  33. end
  34. end
  35.  
  36. def content= (content)
  37. @content = content
  38. end
  39.  
  40. def to_s
  41. open_tag + @content + close_tag
  42. end
  43.  
  44. def open_tag
  45. @@open_tag_prefix + @name + delim_and_attr + @@open_tag_postfix
  46. end
  47.  
  48. def close_tag
  49. @@close_tag_prefix + @name + @@close_tag_postfix
  50. end
  51.  
  52. def delim_and_attr
  53. attr_str = attributes_string()
  54. attributes_delimiter(attr_str) + attr_str
  55. end
  56.  
  57. def attributes_delimiter attr_s
  58. return ' ' if attr_s != ''
  59. ''
  60. end
  61.  
  62. def attributes_string
  63. attr_s = ''
  64. @attributes.each {
  65. |key, value|
  66. attr_s = attr_s + key + "=" + "'" + value + "'" + " "
  67. }
  68. attr_s.strip
  69. end
  70. end
  71.  
  72. # IdealCollection - container to store Ideal objects with the ability of
  73. # generation to the specific format
  74. class IdealCollection
  75.  
  76. def initialize
  77. @state = []
  78. end
  79.  
  80. def << value
  81. @state << value if not @state.include?(value)
  82. end
  83.  
  84. def each
  85. @state.each do |value|
  86. yield(value)
  87. end
  88. end
  89.  
  90. def to_s
  91. @state.to_s
  92. end
  93.  
  94. def generate
  95. result = []
  96. @state.each do |value| result << value.generate() end
  97. result
  98. end
  99.  
  100. def IdealCollection.is_ideal_collection_structure? (structure)
  101. return false if structure.class != Array
  102. structure.each do |value|
  103. return false if not Ideal.is_ideal_structure?(value)
  104. end
  105. true
  106. end
  107.  
  108. end
  109.  
  110. # Ideal - container to store information which can be generated to the special
  111. # format
  112. class Ideal
  113.  
  114. def initialize
  115. @state = {}
  116. end
  117.  
  118. def []= name, value
  119. @state[name] = IdealCollection.new
  120. @state[name] << value
  121. end
  122.  
  123. def [] name
  124. @state[name]
  125. end
  126.  
  127. def to_s
  128. @state.to_s
  129. end
  130.  
  131. def Ideal.is_ideal_structure? struct
  132. valid_types = [String, Fixnum, Float, Bignum]
  133. return true if valid_types.include?(struct.class)
  134. return false if struct.class != Hash
  135. struct.each do |attribute, value|
  136. return false if attribute.class != String
  137. return false if value.class != Array
  138. return false if value != value.uniq
  139. value.each do |key|
  140. return false if not Ideal.is_ideal_structure?(key)
  141. end
  142. end
  143. true
  144. end
  145.  
  146. def is_ideal? key
  147. key.class == Ideal
  148. end
  149.  
  150. def generate
  151. res = {}
  152. @state.each do |attribute, value|
  153. res[attribute] = []
  154. value.each do |key|
  155. if is_ideal?(key)
  156. res[attribute] << key.generate
  157. else
  158. res[attribute] << key
  159. end
  160. end
  161. end
  162. res
  163. end
  164.  
  165. end
  166.  
  167. # Definition of Numeric structure
  168. # Should be used to generate structure definition of Numeric element
  169. class NumericIdealStructureDefinition
  170.  
  171. def type= type
  172. @type = type
  173. end
  174.  
  175. def more_then= numeric
  176. @more_then = numeric
  177. end
  178.  
  179. def less_then= numeric
  180. @less_then = numeric
  181. end
  182.  
  183. def regexp= regexp
  184. @regexp = regexp
  185. end
  186.  
  187. def in= array
  188. @in = array
  189. end
  190.  
  191. def not_in= array
  192. @not_in = array
  193. end
  194.  
  195. def generate
  196. res = {}
  197. if @type != nil
  198. res["type"] = @type
  199. else
  200. raise "Type should be presented for Numeric."
  201. end
  202. res["more_then"] = @more_then if @more_then != nil
  203. res["less_then"] = @less_then if @less_then != nil
  204. res["regexp" ] = @regexp if @regexp != nil
  205. res["in"] = @in if @in != nil
  206. res["not_in"] = @not_in if @not_in !=nil
  207. res = {Numeric => res}
  208. res
  209. end
  210.  
  211. end
  212.  
  213.  
  214. # Definition of String structure
  215. # Should be used to generate structure definition of String element
  216. class StringIdealStructureDefinition
  217.  
  218. def min_length= length
  219. @min_length = length
  220. end
  221.  
  222. def max_length= length
  223. @max_length = length
  224. end
  225.  
  226. def regexp= regexp
  227. @regexp = regexp
  228. end
  229.  
  230. def generate
  231. res = {}
  232. res['min_length'] = @min_length if @min_length != nil
  233. res['max_length'] = @max_length if @max_length != nil
  234. res['regexp'] = @regexp if @regexp != nil
  235. {String => res}
  236. end
  237.  
  238. end
  239.  
  240.  
  241. # Definition of Hash structure
  242. # Should be used to generate structure definition of Hash element
  243. class HashIdealStructureDefinition
  244.  
  245. def initialize
  246. @hash_ideal_structure = {}
  247. end
  248.  
  249. def keys
  250. @hash_ideal_structure.keys
  251. end
  252.  
  253. def []= key, value
  254. @hash_ideal_structure[key] = value
  255. end
  256.  
  257. def generate
  258. res = {}
  259. @hash_ideal_structure.each do |key, value|
  260. res[key] = value.generate
  261. end
  262. {Hash => res}
  263. end
  264.  
  265. end
  266.  
  267.  
  268. # Definition of Ideal Collection structure
  269. # Should be used to generate structure definition of Ideal Collection element
  270. class IdealCollectionStructureDefinition
  271.  
  272. def min_number= min_number
  273. @min_number = min_number
  274. end
  275.  
  276. def max_number= max_number
  277. @max_number = max_number
  278. end
  279.  
  280. def number_array= number_array
  281. @number_array = number_array
  282. end
  283.  
  284. def ideal_structure= ideal_structure
  285. @ideal_structure = ideal_structure
  286. end
  287.  
  288. def generate
  289. res = {}
  290. res["min_number"] = @min_number if @min_number != nil
  291. res["max_number"] = @max_number if @max_number != nil
  292. res["number_array"] = @number_array if @number_array != nil
  293. if @ideal_structure == nil
  294. raise "No ideal structure found."
  295. else
  296. res["ideal_structure"] = @ideal_structure.generate
  297. end
  298. res
  299. end
  300.  
  301. end
  302.  
  303.  
  304. # Simple helper to create XML information useing Element objects from
  305. # ideal data structure
  306. class IdealStructureXML
  307.  
  308. def hash_representation structure
  309. res = ''
  310. structure.each do |key, value|
  311. value.each do |val|
  312. a = Element.new(key)
  313. a.content = render(val)
  314. res = res + a.to_s
  315. end
  316. end
  317. res
  318. end
  319.  
  320. def render structure
  321. return hash_representation(structure) if structure.class == Hash
  322. structure.to_s
  323. end
  324.  
  325. end
  326.  
  327. # Validator of the ideal structure
  328. # Can tell you is your structure is valid idel structure according to its
  329. # definition
  330. class IdealStructureValidator
  331.  
  332. def initialize
  333. @valid_types = [Hash, String, Numeric]
  334. end
  335.  
  336. def validate_hash hash, definition
  337. return false if hash.keys != definition.keys
  338. definition.each do |key, collection|
  339. return false if not validate_collection(hash[key], collection)
  340. end
  341. true
  342. end
  343.  
  344. def validate_string string, definition
  345. min_length = definition['min_length']
  346. str_length = string.length
  347. return false if min_length != nil and not str_length >= min_length
  348. max_length = definition['max_length']
  349. return false if max_length != nil and not str_length <= max_length
  350. regexp = definition['regexp']
  351. return false if regexp != nil and string.scan(regexp).length == 0
  352. true
  353. end
  354.  
  355. def validate_numeric numeric, definition
  356. more_then = definition['more_then']
  357. less_then = definition['less_then']
  358. regexp = definition['regexp']
  359. in_ = definition['in']
  360. not_in = definition['not_in']
  361. return false if more_then != nil and not numeric >= more_then
  362. return false if less_then != nil and not numeric <= less_then
  363. return false if regexp != nil and numeric.to_s.scan(regexp).length == 0
  364. return false if in_ != nil and not in_.include?(numeric)
  365. return false if not_in != nil and not_in.include?(numeric)
  366. true
  367. end
  368.  
  369. def validate_collection collection, definition
  370. length = collection.length
  371. return false if length != collection.uniq.length
  372. min_number = definition['min_number']
  373. return false if min_number != nil and not length >= min_number
  374. max_number = definition['max_number']
  375. return false if max_number != nil and not length <= max_number
  376. number_arr = definition['number_array']
  377. return false if number_arr != nil and not number_arr.include?(length)
  378. def_ideal_structure = definition['ideal_structure']
  379. return false if def_ideal_structure == nil
  380. res = []
  381. collection.each do |value|
  382. res << validate(value, def_ideal_structure)
  383. end
  384. return false if res.include?(false)
  385. true
  386. end
  387.  
  388. def validate input, ideal_structure
  389. ideal_structure.each do |key, value|
  390. return false if not @valid_types.include?(key)
  391. return false if key == Hash and not validate_hash(input, value)
  392. return false if key == String and not validate_string(input, value)
  393. return false if key == Numeric and not validate_numeric(input, value)
  394. end
  395. true
  396. end
  397.  
  398. end
  399.  
  400.  
  401. class IdealTransformation
  402.  
  403. def delimiter info
  404. "<div class='delimiter'>" << info << ":</div>"
  405. end
  406.  
  407. def header
  408. result = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">'
  409. result << "<head>"
  410. result << "<title>"
  411. result << "Test of the Ideal structures"
  412. result << "</title>"
  413. result << "<style type='text/css'>"
  414. result << ".no_users{clear:both; border:1px solid #de7eff;background-color:#eeeeee;color:gray;padding:30px;width:610px;}"
  415. result << ".user_rating{padding:10px;margin:1px;float:left;width:100px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
  416. result << ".user_name{padding:10px;margin:1px;float:left;width:100px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
  417. result << ".user_emails{padding:10px;margin:1px;float:left;width:400px;margin-bottom:10px;border:1px solid #de7eff;background-color:#eeeeee;color:gray;}"
  418. result << ".user{float;left;width:700px;}"
  419. result << ".delimiter{clear:both;}"
  420. result << "</style>"
  421. result << "</head>"
  422. result
  423. end
  424.  
  425. def transform users_data
  426. result = ''
  427. if users_data['users'].length == 0
  428. result << '<div class="no_users">There is no users in the system</div>'
  429. else
  430. result << '<div class="users">'
  431. users_data['users'].each do |user|
  432. result << '<div class="user">'
  433. result << '<div class="user_name">'
  434. result << user['username'].to_s
  435. result << '</div>'
  436. result << '<div class="user_rating">'
  437. result << user['rating'].to_s
  438. result << '</div>'
  439. result << '<div class="user_emails">'
  440. user['email'].each do |email|
  441. result << '<div class="user_email">'
  442. result << email
  443. result << '</div>'
  444. end
  445. result << '</div>'
  446. result << '</div>'
  447. end
  448. result << '</div>'
  449. end
  450. result
  451. end
  452.  
  453. end
  454. end
  455.  
  456.  
  457. class Example
  458.  
  459. def Example.test
  460. # Step 0. Including Ideal module
  461. include Ideal
  462.  
  463. # Step 1. Creation of the ideal descriptor
  464. email_descriptor = StringIdealStructureDefinition.new
  465. email_descriptor.regexp = /[^@]+@[0-9_a-z]+\.[a-z]+/
  466.  
  467. email_collection_descriptor = IdealCollectionStructureDefinition.new
  468. email_collection_descriptor.min_number = 1
  469. email_collection_descriptor.max_number = 7
  470. email_collection_descriptor.ideal_structure = email_descriptor
  471.  
  472. user_rating_descriptor = NumericIdealStructureDefinition.new
  473. user_rating_descriptor.type = Fixnum
  474. user_rating_descriptor.more_then = 0
  475.  
  476. user_rating_collection_descriptor = IdealCollectionStructureDefinition.new
  477. user_rating_collection_descriptor.min_number = 1
  478. user_rating_collection_descriptor.max_number = 1
  479. user_rating_collection_descriptor.ideal_structure = user_rating_descriptor
  480.  
  481. username_descriptor = StringIdealStructureDefinition.new
  482. username_descriptor.regexp = /[0-9A-Za-z_]+/
  483.  
  484. username_collection_descriptor = IdealCollectionStructureDefinition.new
  485. username_collection_descriptor.min_number = 1
  486. username_collection_descriptor.max_number = 1
  487. username_collection_descriptor.ideal_structure = username_descriptor
  488.  
  489. user_descriptor = HashIdealStructureDefinition.new
  490. user_descriptor['username'] = username_collection_descriptor
  491. user_descriptor['rating'] = user_rating_collection_descriptor
  492. user_descriptor['email'] = email_collection_descriptor
  493.  
  494. user_collection_descriptor = IdealCollectionStructureDefinition.new
  495. user_collection_descriptor.min_number = 0
  496. user_collection_descriptor.max_number = 20
  497. user_collection_descriptor.ideal_structure = user_descriptor
  498.  
  499. users_descriptor = HashIdealStructureDefinition.new
  500. users_descriptor['users'] = user_collection_descriptor
  501.  
  502. users_structure_description = users_descriptor.generate
  503.  
  504. # Step 2. Getting data
  505. users_data =
  506. {
  507. "users" =>
  508. [
  509. {
  510. "username" =>
  511. [
  512. "lucifer4u"
  513. ],
  514. "rating" =>
  515. [
  516. 213
  517. ],
  518. "email" =>
  519. [
  520. "lucifer4u@gmail.com",
  521. "lucifer4u@kings.com",
  522. "lucifer4u@swift.com",
  523. "extra@gmail.com",
  524. "system@gmail.com",
  525. "ready@stars.com",
  526. "max@maximus.com"
  527. ]
  528. },
  529. {
  530. "username" =>
  531. [
  532. "niko"
  533. ],
  534. "rating" =>
  535. [
  536. 324
  537. ],
  538. "email" =>
  539. [
  540. "nikodimous@gmail.com",
  541. "system@gmail.com",
  542. "ready@stars.com",
  543. "max@maximus.com"
  544. ]
  545. },
  546. ]
  547. }
  548.  
  549. users_data_2 =
  550. {
  551. "users" =>
  552. [
  553. ]
  554. }
  555.  
  556. users_data_3 =
  557. {
  558. "users" =>
  559. [
  560. {
  561. "username" =>
  562. [
  563. "niko1"
  564. ],
  565. "rating" =>
  566. [
  567. 3241
  568. ],
  569. "email" =>
  570. [
  571. "nikodimous1@gmail.com"
  572. ]
  573. },
  574. {
  575. "username" =>
  576. [
  577. "niko2"
  578. ],
  579. "rating" =>
  580. [
  581. 3242
  582. ],
  583. "email" =>
  584. [
  585. "nikodimous2@gmail.com"
  586. ]
  587. },
  588. {
  589. "username" =>
  590. [
  591. "niko3"
  592. ],
  593. "rating" =>
  594. [
  595. 3243
  596. ],
  597. "email" =>
  598. [
  599. "nikodimous3@gmail.com"
  600. ]
  601. },
  602. ]
  603. }
  604.  
  605.  
  606. # Alternative way using Ideal and Ideal Collection to generate
  607. # ideal structure
  608. a = Ideal.new
  609. a['username'] = "nightwish"
  610. a['rating'] = 3299
  611. a['email'] = "some_email@gmail.com"
  612. a['email'] << "some_mail@gmail.com"
  613. a['email'] << "extra_mail@gmail.com"
  614.  
  615. b = Ideal.new
  616. b['username'] = "rocky"
  617. b['rating'] = 3929
  618. b['email'] = "rocky@rick.com"
  619. b['email'] = "masters@rick.com"
  620.  
  621. c = Ideal.new
  622. c['users'] = a
  623. c['users'] << b
  624.  
  625. users_data_4 = c.generate
  626.  
  627. # Step 3. Validating information
  628. ideal_structure_validator = IdealStructureValidator.new
  629. is_valid = ideal_structure_validator.validate(users_data,
  630. users_structure_description)
  631.  
  632. is_valid_2 = ideal_structure_validator.validate(users_data_2,
  633. users_structure_description)
  634.  
  635. is_valid_3 = ideal_structure_validator.validate(users_data_3,
  636. users_structure_description)
  637.  
  638. is_valid_4 = ideal_structure_validator.validate(users_data_4,
  639. users_structure_description)
  640.  
  641. # Step 4. Transformation of ideal to some other format
  642. ideal_transformation = IdealTransformation.new
  643.  
  644. info = ideal_transformation.header
  645.  
  646. info << ideal_transformation.delimiter("First data structure representation")
  647. if is_valid
  648. info << ideal_transformation.transform(users_data)
  649. end
  650.  
  651. info << ideal_transformation.delimiter("Second data structure representation")
  652. if is_valid_2
  653. info << ideal_transformation.transform(users_data_2)
  654. end
  655.  
  656. info << ideal_transformation.delimiter("Third data structure representation")
  657. if is_valid_3
  658. info << ideal_transformation.transform(users_data_3)
  659. end
  660.  
  661. info << ideal_transformation.delimiter("Forth data structure representation")
  662. if is_valid_4
  663. info << ideal_transformation.transform(users_data_4)
  664. end
  665. info
  666. end
  667.  
  668. end
  669.  
  670.  
  671. # Execution in Controller
  672. class IndexController < ApplicationController
  673.  
  674. def index
  675. @info = Example.test
  676. end
  677.  
  678. end
Add Comment
Please, Sign In to add comment