landable 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +15 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +56 -0
  7. data/Rakefile +22 -0
  8. data/app/controllers/concerns/landable/variables_concern.rb +38 -0
  9. data/app/controllers/landable/api/access_tokens_controller.rb +48 -0
  10. data/app/controllers/landable/api/assets_controller.rb +55 -0
  11. data/app/controllers/landable/api/categories_controller.rb +13 -0
  12. data/app/controllers/landable/api/directories_controller.rb +19 -0
  13. data/app/controllers/landable/api/page_revisions_controller.rb +38 -0
  14. data/app/controllers/landable/api/pages_controller.rb +96 -0
  15. data/app/controllers/landable/api/templates_controller.rb +33 -0
  16. data/app/controllers/landable/api/themes_controller.rb +57 -0
  17. data/app/controllers/landable/api_controller.rb +75 -0
  18. data/app/controllers/landable/application_controller.rb +4 -0
  19. data/app/controllers/landable/public/pages_controller.rb +25 -0
  20. data/app/controllers/landable/public/preview/page_revisions_controller.rb +16 -0
  21. data/app/controllers/landable/public/preview/pages_controller.rb +16 -0
  22. data/app/controllers/landable/public/sitemap_controller.rb +18 -0
  23. data/app/decorators/landable/null_page_decorator.rb +26 -0
  24. data/app/decorators/landable/page_decorator.rb +40 -0
  25. data/app/helpers/landable/application_helper.rb +13 -0
  26. data/app/helpers/landable/pages_helper.rb +20 -0
  27. data/app/models/concerns/landable/has_assets.rb +74 -0
  28. data/app/models/concerns/landable/table_name.rb +12 -0
  29. data/app/models/concerns/landable/traffic/table_name.rb +14 -0
  30. data/app/models/landable/access_token.rb +20 -0
  31. data/app/models/landable/asset.rb +63 -0
  32. data/app/models/landable/asset_search_engine.rb +20 -0
  33. data/app/models/landable/author.rb +12 -0
  34. data/app/models/landable/category.rb +27 -0
  35. data/app/models/landable/directory.rb +23 -0
  36. data/app/models/landable/page.rb +259 -0
  37. data/app/models/landable/page_revision.rb +74 -0
  38. data/app/models/landable/page_search_engine.rb +20 -0
  39. data/app/models/landable/search_engine.rb +39 -0
  40. data/app/models/landable/template.rb +24 -0
  41. data/app/models/landable/theme.rb +20 -0
  42. data/app/models/landable/traffic/access.rb +11 -0
  43. data/app/models/landable/traffic/ad_group.rb +11 -0
  44. data/app/models/landable/traffic/ad_type.rb +11 -0
  45. data/app/models/landable/traffic/attribution.rb +38 -0
  46. data/app/models/landable/traffic/bid_match_type.rb +11 -0
  47. data/app/models/landable/traffic/browser.rb +11 -0
  48. data/app/models/landable/traffic/campaign.rb +11 -0
  49. data/app/models/landable/traffic/city.rb +11 -0
  50. data/app/models/landable/traffic/content.rb +11 -0
  51. data/app/models/landable/traffic/cookie.rb +16 -0
  52. data/app/models/landable/traffic/country.rb +11 -0
  53. data/app/models/landable/traffic/creative.rb +11 -0
  54. data/app/models/landable/traffic/device.rb +11 -0
  55. data/app/models/landable/traffic/device_type.rb +11 -0
  56. data/app/models/landable/traffic/domain.rb +12 -0
  57. data/app/models/landable/traffic/event.rb +12 -0
  58. data/app/models/landable/traffic/event_type.rb +11 -0
  59. data/app/models/landable/traffic/experiment.rb +11 -0
  60. data/app/models/landable/traffic/http_method.rb +11 -0
  61. data/app/models/landable/traffic/ip_address.rb +11 -0
  62. data/app/models/landable/traffic/ip_lookup.rb +12 -0
  63. data/app/models/landable/traffic/keyword.rb +11 -0
  64. data/app/models/landable/traffic/location.rb +11 -0
  65. data/app/models/landable/traffic/match_type.rb +11 -0
  66. data/app/models/landable/traffic/medium.rb +11 -0
  67. data/app/models/landable/traffic/mime_type.rb +11 -0
  68. data/app/models/landable/traffic/network.rb +11 -0
  69. data/app/models/landable/traffic/owner.rb +10 -0
  70. data/app/models/landable/traffic/ownership.rb +10 -0
  71. data/app/models/landable/traffic/page_view.rb +24 -0
  72. data/app/models/landable/traffic/path.rb +13 -0
  73. data/app/models/landable/traffic/placement.rb +11 -0
  74. data/app/models/landable/traffic/platform.rb +11 -0
  75. data/app/models/landable/traffic/position.rb +11 -0
  76. data/app/models/landable/traffic/query_string.rb +12 -0
  77. data/app/models/landable/traffic/referer.rb +11 -0
  78. data/app/models/landable/traffic/region.rb +11 -0
  79. data/app/models/landable/traffic/search_term.rb +11 -0
  80. data/app/models/landable/traffic/source.rb +11 -0
  81. data/app/models/landable/traffic/target.rb +11 -0
  82. data/app/models/landable/traffic/user_agent.rb +28 -0
  83. data/app/models/landable/traffic/user_agent_type.rb +11 -0
  84. data/app/models/landable/traffic/visit.rb +15 -0
  85. data/app/models/landable/traffic/visitor.rb +13 -0
  86. data/app/responders/landable/api_responder.rb +76 -0
  87. data/app/responders/landable/page_render_responder.rb +15 -0
  88. data/app/serializers/landable/access_token_serializer.rb +6 -0
  89. data/app/serializers/landable/asset_serializer.rb +14 -0
  90. data/app/serializers/landable/author_serializer.rb +5 -0
  91. data/app/serializers/landable/category_serializer.rb +5 -0
  92. data/app/serializers/landable/directory_serializer.rb +8 -0
  93. data/app/serializers/landable/page_revision_serializer.rb +15 -0
  94. data/app/serializers/landable/page_serializer.rb +31 -0
  95. data/app/serializers/landable/template_serializer.rb +5 -0
  96. data/app/serializers/landable/theme_serializer.rb +7 -0
  97. data/app/services/landable/authentication_service.rb +44 -0
  98. data/app/services/landable/registration_service.rb +13 -0
  99. data/app/services/landable/render_service.rb +86 -0
  100. data/app/services/landable/tidy_service.rb +155 -0
  101. data/app/uploaders/landable/asset_uploader.rb +9 -0
  102. data/app/validators/path_validator.rb +12 -0
  103. data/app/validators/url_validator.rb +13 -0
  104. data/app/views/templates/preview.liquid +122 -0
  105. data/bin/rails +8 -0
  106. data/bin/redb +7 -0
  107. data/config.ru +7 -0
  108. data/config/cucumber.yml +5 -0
  109. data/config/routes.rb +62 -0
  110. data/db/migrate/20130510221424_create_landable_schema.rb +338 -0
  111. data/db/migrate/20130909182713_landable_pages__add_updated_by.rb +11 -0
  112. data/db/migrate/20130909182715_landable_page_revisions__break_out_snapshot.rb +72 -0
  113. data/db/migrate/20130909191153_landable_pages__add_lock_version.rb +5 -0
  114. data/db/migrate/20131002220041_file_based_themes.rb +12 -0
  115. data/db/migrate/20131008164204_create_head_tag_on_page.rb +19 -0
  116. data/db/migrate/20131008193544_drop_status_codes_model.rb +44 -0
  117. data/db/migrate/20131028145652_add_traffic_schema.rb +276 -0
  118. data/db/migrate/20131101213623_add_dnt_column_to_visits.rb +7 -0
  119. data/db/migrate/20131104224120_add_meta_on_events.rb +7 -0
  120. data/db/migrate/20131106185946_add_index_on_page_revisions_path.rb +6 -0
  121. data/db/migrate/20131106193021_page_revisisons__path_status_code_index.rb +9 -0
  122. data/db/migrate/20131108212501_traffic_owner_ids_are_serials.rb +20 -0
  123. data/db/migrate/20131121150902_add_attribution_id_to_unique_index.rb +10 -0
  124. data/db/migrate/20131216214027_drop_browser_screenshot_tables.rb +6 -0
  125. data/db/migrate/20140128170659_file_backed_templates.rb +8 -0
  126. data/db/migrate/20140205193757_fix_status_codes.rb +24 -0
  127. data/db/migrate/20140206211322_add_response_time_to_traffic_page_views.rb +7 -0
  128. data/db/migrate/20140220170324_add_slug_to_categories.rb +14 -0
  129. data/db/migrate/20140220174630_add_abstract_and_hero_asset_to_pages_and_page_revisions.rb +8 -0
  130. data/db/migrate/20140224205516_rename_traffic_schema.rb +40 -0
  131. data/db/pgtap/pgtap.sql +9034 -0
  132. data/db/test/landable.access_tokens.sql +13 -0
  133. data/db/test/landable.assets.sql +16 -0
  134. data/db/test/landable.authors.sql +22 -0
  135. data/db/test/landable.categories.sql +9 -0
  136. data/db/test/landable.page_revisions.sql +41 -0
  137. data/db/test/landable.pages.sql +19 -0
  138. data/db/test/landable.templates.sql +15 -0
  139. data/db/test/landable.themes.sql +25 -0
  140. data/doc/schema/access_token.json +22 -0
  141. data/doc/schema/asset.json +65 -0
  142. data/doc/schema/author.json +30 -0
  143. data/doc/schema/directory.json +24 -0
  144. data/doc/schema/page.json +95 -0
  145. data/doc/schema/page_revision.json +70 -0
  146. data/doc/schema/theme.json +37 -0
  147. data/doc/schema/uuid.json +6 -0
  148. data/features/api/access_tokens.feature +84 -0
  149. data/features/api/assets.feature +46 -0
  150. data/features/api/cors.feature +25 -0
  151. data/features/api/pages.feature +42 -0
  152. data/features/api/preview.feature +16 -0
  153. data/features/api/templates.feature +33 -0
  154. data/features/api/themes.feature +33 -0
  155. data/features/liquid/body.feature +35 -0
  156. data/features/liquid/drops/categories.feature +54 -0
  157. data/features/liquid/tags.feature +168 -0
  158. data/features/public/content_types.feature +17 -0
  159. data/features/public/publishing.feature +45 -0
  160. data/features/public/status_codes.feature +25 -0
  161. data/features/public/views.feature +17 -0
  162. data/features/step_definitions/asset_steps.rb +60 -0
  163. data/features/step_definitions/core_api_steps.rb +139 -0
  164. data/features/step_definitions/debug_steps.rb +3 -0
  165. data/features/step_definitions/factory_steps.rb +124 -0
  166. data/features/step_definitions/html_steps.rb +9 -0
  167. data/features/step_definitions/liquid_steps.rb +79 -0
  168. data/features/step_definitions/revision_steps.rb +5 -0
  169. data/features/step_definitions/theme_steps.rb +43 -0
  170. data/features/support/env.rb +66 -0
  171. data/features/support/usefulness.rb +13 -0
  172. data/landable.gemspec +54 -0
  173. data/lib/generators/landable/collection/collection_generator.rb +0 -0
  174. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%.less +0 -0
  175. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/mixins.less +0 -0
  176. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/variables.less +0 -0
  177. data/lib/generators/landable/component/component_generator.rb +0 -0
  178. data/lib/generators/landable/component/templates/javascripts/landable/%file_name%.less +0 -0
  179. data/lib/generators/landable/component/templates/stylesheets/landable/%file_name%.less +0 -0
  180. data/lib/generators/landable/install_generator.rb +19 -0
  181. data/lib/generators/landable/landable_generator.rb +22 -0
  182. data/lib/generators/templates/landable.rb +34 -0
  183. data/lib/landable.rb +30 -0
  184. data/lib/landable/configuration.rb +115 -0
  185. data/lib/landable/core_ext/ipaddr.rb +18 -0
  186. data/lib/landable/engine.rb +69 -0
  187. data/lib/landable/error.rb +16 -0
  188. data/lib/landable/inflections.rb +4 -0
  189. data/lib/landable/layout.rb +60 -0
  190. data/lib/landable/liquid.rb +27 -0
  191. data/lib/landable/liquid/asset_tags.rb +76 -0
  192. data/lib/landable/liquid/drops.rb +46 -0
  193. data/lib/landable/liquid/filters.rb +11 -0
  194. data/lib/landable/liquid/tags.rb +91 -0
  195. data/lib/landable/migration.rb +40 -0
  196. data/lib/landable/mime_types.rb +15 -0
  197. data/lib/landable/partial.rb +46 -0
  198. data/lib/landable/seeds.rb +36 -0
  199. data/lib/landable/traffic.rb +34 -0
  200. data/lib/landable/traffic/crawl_tracker.rb +9 -0
  201. data/lib/landable/traffic/noop_tracker.rb +8 -0
  202. data/lib/landable/traffic/ping_tracker.rb +9 -0
  203. data/lib/landable/traffic/scan_tracker.rb +9 -0
  204. data/lib/landable/traffic/scrape_tracker.rb +9 -0
  205. data/lib/landable/traffic/tracker.rb +283 -0
  206. data/lib/landable/traffic/user_tracker.rb +65 -0
  207. data/lib/landable/version.rb +10 -0
  208. data/lib/tasks/landable/cucumber.rake +67 -0
  209. data/lib/tasks/landable/data.rake +166 -0
  210. data/lib/tasks/landable/pgtap.rake +26 -0
  211. data/lib/tasks/landable/rdoc.rake +11 -0
  212. data/lib/tasks/landable/seed.rake +16 -0
  213. data/lib/tasks/landable/spec.rake +15 -0
  214. data/script/cucumber +10 -0
  215. data/spec/concerns/landable/has_assets_spec.rb +75 -0
  216. data/spec/concerns/landable/table_name_spec.rb +15 -0
  217. data/spec/concerns/landable/traffic/table_name_spec.rb +16 -0
  218. data/spec/controllers/concerns/landable/variables_concern_spec.rb +66 -0
  219. data/spec/controllers/landable/api/assets_controller_spec.rb +24 -0
  220. data/spec/controllers/landable/api/categories_controller_spec.rb +45 -0
  221. data/spec/controllers/landable/api/directories_controller_spec.rb +56 -0
  222. data/spec/controllers/landable/api/page_revisions_controller_spec.rb +29 -0
  223. data/spec/controllers/landable/api/pages_controller_spec.rb +271 -0
  224. data/spec/controllers/landable/api_controller_spec.rb +189 -0
  225. data/spec/controllers/public/preview/page_revisions_controller_spec.rb +41 -0
  226. data/spec/controllers/public/preview/pages_controller_spec.rb +36 -0
  227. data/spec/controllers/public/sitemap_controller_spec.rb +25 -0
  228. data/spec/decorators/page_decorator_spec.rb +90 -0
  229. data/spec/dummy/README.rdoc +28 -0
  230. data/spec/dummy/Rakefile +6 -0
  231. data/spec/dummy/app/assets/images/foo.jpg +0 -0
  232. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  233. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  234. data/spec/dummy/app/controllers/application_controller.rb +10 -0
  235. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  236. data/spec/dummy/app/controllers/priority_controller.rb +7 -0
  237. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  238. data/spec/dummy/app/mailers/.keep +0 -0
  239. data/spec/dummy/app/models/.keep +0 -0
  240. data/spec/dummy/app/models/concerns/.keep +0 -0
  241. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  242. data/spec/dummy/app/views/layouts/priority.html.erb +18 -0
  243. data/spec/dummy/app/views/partials/_foobazz.html +1 -0
  244. data/spec/dummy/app/views/priority/show.html.erb +11 -0
  245. data/spec/dummy/bin/bundle +3 -0
  246. data/spec/dummy/bin/rails +4 -0
  247. data/spec/dummy/bin/rake +4 -0
  248. data/spec/dummy/config.ru +4 -0
  249. data/spec/dummy/config/application.rb +21 -0
  250. data/spec/dummy/config/boot.rb +5 -0
  251. data/spec/dummy/config/database.yml +60 -0
  252. data/spec/dummy/config/environment.rb +5 -0
  253. data/spec/dummy/config/environments/development.rb +29 -0
  254. data/spec/dummy/config/environments/production.rb +80 -0
  255. data/spec/dummy/config/environments/test.rb +42 -0
  256. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  257. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  258. data/spec/dummy/config/initializers/inflections.rb +16 -0
  259. data/spec/dummy/config/initializers/landable.rb +22 -0
  260. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  261. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  262. data/spec/dummy/config/initializers/session_store.rb +3 -0
  263. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  264. data/spec/dummy/config/locales/en.yml +23 -0
  265. data/spec/dummy/config/routes.rb +4 -0
  266. data/spec/dummy/db/structure.sql +3736 -0
  267. data/spec/dummy/lib/assets/.keep +0 -0
  268. data/spec/dummy/log/.keep +0 -0
  269. data/spec/dummy/public/404.html +58 -0
  270. data/spec/dummy/public/422.html +58 -0
  271. data/spec/dummy/public/500.html +57 -0
  272. data/spec/dummy/public/favicon.ico +0 -0
  273. data/spec/factories/asset.rb +29 -0
  274. data/spec/factories/authors.rb +12 -0
  275. data/spec/factories/category.rb +6 -0
  276. data/spec/factories/page_revision.rb +6 -0
  277. data/spec/factories/pages.rb +33 -0
  278. data/spec/factories/template.rb +13 -0
  279. data/spec/factories/theme.rb +14 -0
  280. data/spec/fixtures/assets/cthulhu.jpg +0 -0
  281. data/spec/fixtures/assets/panda.png +0 -0
  282. data/spec/fixtures/assets/sloth.png +0 -0
  283. data/spec/fixtures/assets/small.pdf +0 -0
  284. data/spec/helpers/pages_helper_spec.rb +35 -0
  285. data/spec/lib/landable/configuration_spec.rb +20 -0
  286. data/spec/lib/landable/layout_spec.rb +25 -0
  287. data/spec/lib/landable/liquid_spec.rb +24 -0
  288. data/spec/lib/landable/migration_spec.rb +51 -0
  289. data/spec/lib/landable/partial_spec.rb +84 -0
  290. data/spec/lib/landable/tracking_spec.rb +62 -0
  291. data/spec/lib/landable/traffic_spec.rb +45 -0
  292. data/spec/models/landable/access_token_spec.rb +13 -0
  293. data/spec/models/landable/asset_spec.rb +48 -0
  294. data/spec/models/landable/directory_spec.rb +36 -0
  295. data/spec/models/landable/page/errors_spec.rb +30 -0
  296. data/spec/models/landable/page_revision_spec.rb +75 -0
  297. data/spec/models/landable/page_spec.rb +377 -0
  298. data/spec/models/landable/template_spec.rb +47 -0
  299. data/spec/models/landable/theme_spec.rb +8 -0
  300. data/spec/responders/page_render_responder_spec.rb +43 -0
  301. data/spec/routing/public_page_route_spec.rb +36 -0
  302. data/spec/services/landable/authentication_service_spec.rb +61 -0
  303. data/spec/services/landable/render_service_spec.rb +103 -0
  304. data/spec/services/landable/tidy_service_spec.rb +157 -0
  305. data/spec/spec_helper.rb +38 -0
  306. data/spec/support/behaviors.rb +107 -0
  307. data/spec/support/carrier_wave.rb +17 -0
  308. data/spec/support/categories.yml +2 -0
  309. data/spec/support/helpers.rb +22 -0
  310. metadata +795 -0
@@ -0,0 +1,74 @@
1
+ require_dependency 'landable/has_assets'
2
+
3
+ module Landable
4
+ class PageRevision < ActiveRecord::Base
5
+ include Landable::Engine.routes.url_helpers
6
+ include Landable::HasAssets
7
+ include Landable::TableName
8
+
9
+ @@ignored_page_attributes = [
10
+ 'page_id',
11
+ 'imported_at',
12
+ 'created_at',
13
+ 'updated_at',
14
+ 'published_revision_id',
15
+ 'is_publishable',
16
+ 'updated_by_author_id',
17
+ 'lock_version'
18
+ ]
19
+
20
+ cattr_accessor :ignored_page_attributes
21
+
22
+ belongs_to :author
23
+ belongs_to :page, inverse_of: :revisions
24
+ has_many :screenshots, class_name: 'Landable::Screenshot', as: :screenshotable
25
+
26
+ def page_id=(id)
27
+ # set the value
28
+ self[:page_id] = id
29
+
30
+ # copy grab attributes from the page
31
+ self.title = page.title
32
+ self.body = page.body
33
+ self.head_content = page.head_content
34
+ self.path = page.path
35
+ self.status_code = page.status_code
36
+ self.category_id = page.category_id
37
+ self.theme_id = page.theme_id
38
+ self.meta_tags = page.meta_tags
39
+ self.redirect_url = page.redirect_url
40
+ self.abstract = page.abstract
41
+ self.hero_asset_id = page.hero_asset_id
42
+ end
43
+
44
+ def snapshot
45
+ Page.new(title: self.title,
46
+ meta_tags: page.meta_tags,
47
+ head_content: page.head_content,
48
+ body: self.body,
49
+ path: self.path,
50
+ redirect_url: self.redirect_url,
51
+ status_code: self.status_code,
52
+ theme_id: self.theme_id,
53
+ category_id: self.category_id,
54
+ abstract: self.abstract,
55
+ hero_asset_id: self.hero_asset_id)
56
+ end
57
+
58
+ def publish!
59
+ update_attribute :is_published, true
60
+ end
61
+
62
+ def unpublish!
63
+ update_attribute :is_published, false
64
+ end
65
+
66
+ def preview_url
67
+ public_preview_page_revision_url(self)
68
+ end
69
+
70
+ def preview_path
71
+ public_preview_page_revision_path(self)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,20 @@
1
+ require_dependency 'landable/search_engine'
2
+ require_dependency 'landable/page'
3
+
4
+ module Landable
5
+ class PageSearchEngine < SearchEngine
6
+ def initialize(filters, options = {})
7
+ super Page.all, filters, options
8
+ end
9
+
10
+ def filter_by!(filters)
11
+ if ids = as_array(filters[:ids])
12
+ @scope = @scope.where(page_id: ids)
13
+ end
14
+
15
+ if path = filters[:path].presence
16
+ @scope = @scope.with_fuzzy_path(path)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ module Landable
2
+ class SearchEngine
3
+ def initialize(base_scope, filters, options = {})
4
+ @scope = base_scope
5
+
6
+ order! options[:order]
7
+ limit! options[:limit]
8
+
9
+ filter_by!(filters)
10
+ end
11
+
12
+ def results
13
+ @scope
14
+ end
15
+
16
+ def meta
17
+ { search: { total_results: @scope.count } }
18
+ end
19
+
20
+ def filter_by!(filters)
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def order!(order)
25
+ @scope = @scope.order(order) if order
26
+ end
27
+
28
+ def limit!(limit)
29
+ @scope = @scope.limit(limit) if limit
30
+ end
31
+
32
+ protected
33
+
34
+ def as_array(value)
35
+ array = Array(value)
36
+ array if array.any?
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ module Landable
2
+ class Template < ActiveRecord::Base
3
+ include Landable::TableName
4
+
5
+ validates_presence_of :name, :slug, :description
6
+ validates_uniqueness_of :name, case_sensitive: false
7
+ validates_uniqueness_of :slug, case_sensitive: false
8
+
9
+ def name= val
10
+ self[:name] = val
11
+ self[:slug] ||= (val && val.underscore.gsub(/[^\w_]/, '_').gsub(/_{2,}/, '_'))
12
+ end
13
+
14
+ def partial?
15
+ file.present?
16
+ end
17
+
18
+ class << self
19
+ def create_from_partials!
20
+ Partial.all.map(&:to_template)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require_dependency 'landable/has_assets'
2
+
3
+ module Landable
4
+ class Theme < ActiveRecord::Base
5
+ include Landable::TableName
6
+ include Landable::HasAssets
7
+
8
+ validates_presence_of :name, :description
9
+ validates_uniqueness_of :name, case_sensitive: false
10
+
11
+ has_many :pages, inverse_of: :theme
12
+
13
+ class << self
14
+ def create_from_layouts!
15
+ return unless table_exists?
16
+ Layout.all.map(&:to_theme)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Access < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_for :path, class_name: Path
7
+
8
+ belongs_to :visitor
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class AdGroup < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :ad_group, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class AdType < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :ad_type, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ module Landable
2
+ module Traffic
3
+ class Attribution < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+ KEYS = %w[ad_type ad_group bid_match_type campaign content creative device_type experiment keyword match_type medium network placement position search_term source target]
6
+
7
+ self.record_timestamps = false
8
+
9
+ KEYS.each do |key|
10
+ lookup_for key.to_sym, class_name: "Landable::Traffic::#{key.classify}".constantize
11
+ end
12
+
13
+ has_many :visits
14
+
15
+ class << self
16
+ def transform(parameters)
17
+ hash = parameters.slice(*KEYS)
18
+
19
+ filter = {}
20
+
21
+ hash.each do |k, v|
22
+ filter[k.foreign_key] = "Landable::Traffic::#{k.classify}".constantize[v]
23
+ end
24
+
25
+ filter
26
+ end
27
+
28
+ def lookup(parameters)
29
+ where(transform(parameters)).first_or_create
30
+ end
31
+
32
+ def digest(parameters)
33
+ Digest::SHA2.base64digest transform(parameters).values.join
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class BidMatchType < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :bid_match_type, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Browser < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :browser, cache: 50, find_or_create: true
7
+
8
+ has_many :user_agents
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Campaign < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :campaign, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class City < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :city, cache: 50, find_or_create: true
7
+
8
+ has_many :locations
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Content < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :content, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Landable
2
+ module Traffic
3
+ class Cookie < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :cookie_id, cache: 100, find: true
7
+
8
+ has_many :ownerships
9
+ has_many :visits
10
+
11
+ after_initialize do
12
+ self.id ||= SecureRandom.uuid
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Country < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :country, cache: true, find_or_create: true
7
+
8
+ has_many :locations
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Creative < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :creative, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Device < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :device, cache: 50, find_or_create: true
7
+
8
+ has_many :user_agents
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class DeviceType < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :device_type, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Landable
2
+ module Traffic
3
+ class Domain < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :domain, cache: 50, find_or_create: true
7
+
8
+ has_many :ip_lookups
9
+ has_many :referers
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Landable
2
+ module Traffic
3
+ class Event < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+ self.record_timestamps = false
6
+
7
+ lookup_for :event_type, class_name: EventType, symbolize: true
8
+
9
+ belongs_to :visit
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class EventType < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :event_type, cache: true, find_or_create: true
7
+
8
+ has_many :events
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Landable
2
+ module Traffic
3
+ class Experiment < ActiveRecord::Base
4
+ include Landable::Traffic::TableName
5
+
6
+ lookup_by :experiment, cache: 50, find_or_create: true
7
+
8
+ has_many :attributions
9
+ end
10
+ end
11
+ end