hubstats 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/app/assets/javascripts/hubstats/application.js +8 -3
- data/app/assets/javascripts/hubstats/pull_requests.js +159 -0
- data/app/assets/stylesheets/hubstats/application.css +47 -0
- data/app/assets/stylesheets/hubstats/pull_requests.css +3 -0
- data/app/controllers/hubstats/pull_requests_controller.rb +19 -2
- data/app/controllers/hubstats/repos_controller.rb +27 -10
- data/app/controllers/hubstats/users_controller.rb +12 -1
- data/app/models/hubstats/label.rb +15 -0
- data/app/models/hubstats/pull_request.rb +36 -14
- data/app/views/hubstats/metrics/_comments_table.html.erb +9 -6
- data/app/views/hubstats/metrics/_pulls_table.html.erb +1 -1
- data/app/views/hubstats/partials/_comment.html.erb +13 -0
- data/app/views/hubstats/partials/_header.html.erb +28 -10
- data/app/views/hubstats/partials/_pull.html.erb +24 -0
- data/app/views/hubstats/pull_requests/index.html.erb +52 -5
- data/app/views/hubstats/pull_requests/repo_index.html.erb +8 -0
- data/app/views/hubstats/pull_requests/show.html.erb +5 -9
- data/app/views/hubstats/repos/dashboard.html.erb +21 -0
- data/app/views/hubstats/repos/index.html.erb +2 -10
- data/app/views/hubstats/users/show.html.erb +9 -3
- data/config/routes.rb +6 -3
- data/db/migrate/20140604130339_create_hubstats_pull_requests.rb +12 -12
- data/db/migrate/20140604130457_create_hubstats_users.rb +4 -3
- data/db/migrate/20140604130504_create_hubstats_comments.rb +12 -9
- data/db/migrate/20140604130550_create_hubstats_repos.rb +15 -15
- data/db/migrate/20140703173123_create_hubstats_labels.rb +9 -0
- data/db/migrate/20140703200752_create_hubstats_labels_pull_requests.rb +8 -0
- data/lib/hubstats/events_handler.rb +4 -6
- data/lib/hubstats/github_api.rb +21 -0
- data/lib/hubstats/version.rb +1 -1
- data/lib/tasks/populate_task.rake +22 -3
- data/test/dummy/db/migrate/{20140702234357_create_hubstats_pull_requests.hubstats.rb → 20140703201046_create_hubstats_pull_requests.hubstats.rb} +12 -12
- data/test/dummy/db/migrate/{20140702234358_create_hubstats_users.hubstats.rb → 20140703201047_create_hubstats_users.hubstats.rb} +4 -3
- data/test/dummy/db/migrate/{20140702234359_create_hubstats_comments.hubstats.rb → 20140703201048_create_hubstats_comments.hubstats.rb} +12 -9
- data/test/dummy/db/migrate/{20140702234360_create_hubstats_repos.hubstats.rb → 20140703201049_create_hubstats_repos.hubstats.rb} +15 -15
- data/test/dummy/db/migrate/20140703201050_create_hubstats_labels.hubstats.rb +10 -0
- data/test/dummy/db/migrate/20140703201051_create_hubstats_labels_pull_requests.hubstats.rb +9 -0
- data/test/dummy/db/schema.rb +68 -57
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/production.log +3 -0
- data/test/dummy/log/test.log +6688 -0
- data/test/dummy/tmp/cache/assets/C6A/070/sprockets%2F722061c11245ef57a10b2a8b249536a6 +0 -0
- data/test/dummy/tmp/cache/assets/C80/780/sprockets%2Fc1cf9f40564205993336f5119dc8301d +0 -0
- data/test/dummy/tmp/cache/assets/C97/B60/sprockets%2Faec576e1f9385471867ed31d55077188 +0 -0
- data/test/dummy/tmp/cache/assets/CA0/2B0/sprockets%2F00310502bf37155c1d795a84d46e1fa7 +0 -0
- data/test/dummy/tmp/cache/assets/CA2/FC0/sprockets%2Fc0a86d68e0c4a2374484370da89d1000 +0 -0
- data/test/dummy/tmp/cache/assets/CAC/770/sprockets%2F6f6eca43ba817098511ce082222681e7 +0 -0
- data/test/dummy/tmp/cache/assets/CAD/3D0/sprockets%2F781852b612e12270af6602bdb8f985a4 +0 -0
- data/test/dummy/tmp/cache/assets/CBC/4C0/sprockets%2F43796510bea9e088167ff07f3d0a8484 +0 -0
- data/test/dummy/tmp/cache/assets/CD1/790/sprockets%2F825aafb951c27a7ca74309144540cc51 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CDA/040/sprockets%2Fb4d91e72711bf28f408e6501a40539bf +0 -0
- data/test/dummy/tmp/cache/assets/{CDC/260/sprockets%2F3e779895354a0eb2c14e0a37a9b143f3 → CDB/3F0/sprockets%2Fe3dd42740d72fd4147cc2bc430554858} +0 -0
- data/test/dummy/tmp/cache/assets/CE3/FF0/sprockets%2Fcef2250ca879df25864e46743811b34a +0 -0
- data/test/dummy/tmp/cache/assets/CE5/950/sprockets%2F6011591ca606d6465ffe00aa59798f4f +0 -0
- data/test/dummy/tmp/cache/assets/CED/160/sprockets%2Fd17778dcc64ba05d748e9596851b42b2 +0 -0
- data/test/dummy/tmp/cache/assets/D00/000/sprockets%2Fca55ed2e244f0ae2454363027cae0865 +0 -0
- data/test/dummy/tmp/cache/assets/D1E/160/sprockets%2F6b06e88c694fe253732afa662e4b83d8 +0 -0
- data/test/dummy/tmp/cache/assets/D1E/690/sprockets%2F87b902b589445ed855fa47700d19ddcd +0 -0
- data/test/dummy/tmp/cache/assets/D20/FF0/sprockets%2F941bab9382328e98fd569386d1ec0af5 +0 -0
- data/test/dummy/tmp/cache/assets/D21/C00/sprockets%2F8d98ccfd866c7b6d27c557031ed18173 +0 -0
- data/test/dummy/tmp/cache/assets/D29/830/sprockets%2Fd625d52591e79dd7ea694da983763e1f +0 -0
- data/test/dummy/tmp/cache/assets/D2F/DC0/sprockets%2Fdb2533855a0541d30ee3fb4c952a9ab3 +0 -0
- data/test/dummy/tmp/cache/assets/D32/070/sprockets%2F7e8b1f51c452335eaa6dc3ac440332f9 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D38/CB0/sprockets%2F29c1b9d8419784ce13da2b3f174ac2d1 +0 -0
- data/test/dummy/tmp/cache/assets/D3A/D50/sprockets%2Ff40159b97cbd42cd120ab6db69d67182 +0 -0
- data/test/dummy/tmp/cache/assets/D3D/470/sprockets%2Ff6740e85131eb3c5c3836792c5db0ccd +0 -0
- data/test/dummy/tmp/cache/assets/D45/FE0/sprockets%2F71e7d22428abdfaf957abc097437178b +0 -0
- data/test/dummy/tmp/cache/assets/D46/F70/sprockets%2Ff8b0242cb6b63299e67b9356ed34e3bc +0 -0
- data/test/dummy/tmp/cache/assets/D47/F60/sprockets%2F275572ae8865ec1ffa9a17b4c658b0b6 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D51/7F0/sprockets%2Fe483e54cab3b78e5959d5bc422692ff5 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D5D/880/sprockets%2F49469a907bfe2696eb66b3d69d69cc6b +0 -0
- data/test/dummy/tmp/cache/assets/D62/F50/sprockets%2Fe4fa88230ba5d4b30cd36d170c2f57a8 +0 -0
- data/test/dummy/tmp/cache/assets/D68/7C0/sprockets%2F53c50d8f33708cb75b09c0d4c7d3caf3 +0 -0
- data/test/dummy/tmp/cache/assets/D6B/570/sprockets%2F70c5d0418ce288f30ad3d949fd31a0ef +0 -0
- data/test/dummy/tmp/cache/assets/D7E/2C0/sprockets%2Fe11fb7d12e6f167b56f4b939b65c97fb +0 -0
- data/test/dummy/tmp/cache/assets/D7F/5B0/sprockets%2F842879ad233dad55dc6c3f23eed939f6 +0 -0
- data/test/dummy/tmp/cache/assets/D85/310/sprockets%2F5bfbaf42e04878ffee659890736e5ac4 +0 -0
- data/test/dummy/tmp/cache/assets/D95/E70/sprockets%2F71e192cc81e15e41babc78da4a549b5b +0 -0
- data/test/dummy/tmp/cache/assets/D9A/300/sprockets%2F044ebd5e75412ceead3574d6d3eed550 +0 -0
- data/test/dummy/tmp/cache/assets/D9E/0F0/sprockets%2Fddaeeb8234f096140f35c06ff538bbe6 +0 -0
- data/test/dummy/tmp/cache/assets/DAA/D80/sprockets%2Fe7bd68eb95e047454adfc49e5f0b8e11 +0 -0
- data/test/dummy/tmp/cache/assets/DC7/5C0/sprockets%2F4af3c5fb39b4b93a7fc1c5db2c05c583 +0 -0
- data/test/dummy/tmp/cache/assets/DD8/5A0/sprockets%2Fdc77251d6c233eeecb693ff083f35eee +0 -0
- data/test/dummy/tmp/cache/assets/{BF9/050/sprockets%2F15110619558921cc177344f4d898707b → DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994} +0 -0
- data/test/dummy/tmp/cache/assets/{CE0/3F0/sprockets%2F2172471af487ddf3277bc0cf35e45175 → DDD/E60/sprockets%2Fe81c794a9e4d16cb9e35c8b8ee5b6b2c} +0 -0
- data/test/dummy/tmp/cache/assets/DDE/160/sprockets%2Fad7ae04f67dc2e97b7956ea219e4bc8f +0 -0
- data/test/dummy/tmp/cache/assets/DDF/3E0/sprockets%2F59b0fb9e71148d95cf2e9e90c29cfacd +0 -0
- data/test/dummy/tmp/cache/assets/DF9/4E0/sprockets%2F79fba73941daca3fad36e2d68bf243aa +0 -0
- data/test/dummy/tmp/cache/assets/{C8E/170/sprockets%2F0f711299ca198f9725c1db4935d47446 → E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af} +0 -0
- data/test/dummy/tmp/cache/assets/E06/450/sprockets%2Ffcd574cdf1957cd4acd029f0de961dd5 +0 -0
- data/test/dummy/tmp/cache/assets/E0B/7F0/sprockets%2Fec7ca66fae22eb868a78c2d97dd5c27a +0 -0
- data/test/dummy/tmp/cache/assets/E0F/CE0/sprockets%2F5c479ac6683cdd3e7ed01defd75e7be6 +0 -0
- data/test/dummy/tmp/cache/assets/E10/920/sprockets%2Fe2793fe8a9f6773e8d2d5bececb01b7f +0 -0
- data/test/dummy/tmp/cache/assets/E30/D10/sprockets%2F5be1e5ad45bde1dbd7fb9f8d720277ea +0 -0
- data/test/dummy/tmp/cache/assets/E41/A20/sprockets%2F23cef5db9fa9d95cf84a2c688b5fe6ab +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- metadata +129 -246
- data/test/dummy/tmp/cache/assets/C31/590/sprockets%2Ff47655ec02a789734a9457367270951a +0 -0
- data/test/dummy/tmp/cache/assets/C3F/980/sprockets%2F4425b71da600554d5351206534749bcb +0 -0
- data/test/dummy/tmp/cache/assets/C52/560/sprockets%2F0c760b641530192770a8ea78b428c976 +0 -0
- data/test/dummy/tmp/cache/assets/C61/2A0/sprockets%2F3594884c048946898cddd41122bd5571 +0 -0
- data/test/dummy/tmp/cache/assets/C6B/B30/sprockets%2F47b8c8579e50463c994bf7194a626518 +0 -0
- data/test/dummy/tmp/cache/assets/C72/0E0/sprockets%2F8e8f8a05374b7958964ee35121985d67 +0 -0
- data/test/dummy/tmp/cache/assets/C74/0F0/sprockets%2Fd2956e2971f0efb507249795868727f7 +0 -0
- data/test/dummy/tmp/cache/assets/C7D/DB0/sprockets%2F7582164669b0032164c4fc37fe0826bb +0 -0
- data/test/dummy/tmp/cache/assets/C85/1D0/sprockets%2F7e242c866f942351653c1676c91dc11e +0 -0
- data/test/dummy/tmp/cache/assets/C85/7B0/sprockets%2Feb946492dd699986b5694488d45e6298 +0 -0
- data/test/dummy/tmp/cache/assets/C86/5A0/sprockets%2F429945133e54f0e28c43bf5ca3395916 +0 -0
- data/test/dummy/tmp/cache/assets/C9D/840/sprockets%2F1d8ae17d505b1eb5051eb25077134816 +0 -0
- data/test/dummy/tmp/cache/assets/CAE/790/sprockets%2Fe77520c0e7472601dc58113e9b6d09c6 +0 -0
- data/test/dummy/tmp/cache/assets/CAF/1C0/sprockets%2F3c35dc6950a910a9df728095550c7c50 +0 -0
- data/test/dummy/tmp/cache/assets/CC3/1D0/sprockets%2F75475825e4cd042e377882e60991ecec +0 -0
- data/test/dummy/tmp/cache/assets/CC7/920/sprockets%2F9559c6b85ec6d794191fb0f51d643656 +0 -0
- data/test/dummy/tmp/cache/assets/CC8/5C0/sprockets%2F611f6be949d97f1cd071f8474966716a +0 -0
- data/test/dummy/tmp/cache/assets/CCE/2E0/sprockets%2Ff9cb57cb6014c1432cb221419f44d803 +0 -0
- data/test/dummy/tmp/cache/assets/CCF/2A0/sprockets%2F52350a36ad30e5c57d3241d9e216fd06 +0 -0
- data/test/dummy/tmp/cache/assets/CD0/150/sprockets%2Fd29250c44b3ce63c844744aa1b61a545 +0 -0
- data/test/dummy/tmp/cache/assets/CD2/400/sprockets%2Fef5170f25214b824208d19c1d4cc1b58 +0 -0
- data/test/dummy/tmp/cache/assets/CD6/820/sprockets%2F6b25810492b76c71eac09c720c5a2d75 +0 -0
- data/test/dummy/tmp/cache/assets/CDD/720/sprockets%2F1229cde58b70f53701f34b3e85a8b822 +0 -0
- data/test/dummy/tmp/cache/assets/CE8/F60/sprockets%2F4f90c6089a97e1b09e1d05ae306d5589 +0 -0
- data/test/dummy/tmp/cache/assets/CE9/AF0/sprockets%2Ffe8a227c3a37660537ef955f27353ac6 +0 -0
- data/test/dummy/tmp/cache/assets/CED/340/sprockets%2F56beb0aa20b4b0180e2cf409309731c1 +0 -0
- data/test/dummy/tmp/cache/assets/CF3/F10/sprockets%2F49d462fdbf815da37e08664853c7c980 +0 -0
- data/test/dummy/tmp/cache/assets/D02/4E0/sprockets%2Faa7feb4a2859275206a4a3830c53fa25 +0 -0
- data/test/dummy/tmp/cache/assets/D02/5B0/sprockets%2Fccd3c5176523034e06a08f2bce1468c6 +0 -0
- data/test/dummy/tmp/cache/assets/D0D/860/sprockets%2F50fd288c9613092dd975ba2067ba42cd +0 -0
- data/test/dummy/tmp/cache/assets/D0E/470/sprockets%2Fa3ce5b5a0016444e9cd58e6b19b15759 +0 -0
- data/test/dummy/tmp/cache/assets/D13/150/sprockets%2F134903ad1d71e9b5d9055f76f7e070ed +0 -0
- data/test/dummy/tmp/cache/assets/D13/2D0/sprockets%2F9a9e2a3c4c3d7d4083c55991e19fa170 +0 -0
- data/test/dummy/tmp/cache/assets/D13/A90/sprockets%2F43bdaff41d76c03d404a6e541c788966 +0 -0
- data/test/dummy/tmp/cache/assets/D15/570/sprockets%2F2a83b24fd5c03c9b568ce98f017d3276 +0 -0
- data/test/dummy/tmp/cache/assets/D16/B40/sprockets%2F2f42a66eb4e9c3c46c19767e3c2b5950 +0 -0
- data/test/dummy/tmp/cache/assets/D17/D80/sprockets%2F7fb4dca0599ec86773142a87e2123ee4 +0 -0
- data/test/dummy/tmp/cache/assets/D19/2D0/sprockets%2Fb45a7b27824f7ec1ba4b89d3579462d5 +0 -0
- data/test/dummy/tmp/cache/assets/D1A/2B0/sprockets%2Fa198485c386ab897195c4ef12057acdc +0 -0
- data/test/dummy/tmp/cache/assets/D1A/F80/sprockets%2F3e61358128047c3fd738bb87f19e5dae +0 -0
- data/test/dummy/tmp/cache/assets/D20/A00/sprockets%2F8808c57306ee605a6a96aa5e7ec5c669 +0 -0
- data/test/dummy/tmp/cache/assets/D24/CF0/sprockets%2F69b4859d5fed395dfc00c47a28c47628 +0 -0
- data/test/dummy/tmp/cache/assets/D25/C60/sprockets%2F3f4d4f83ad9bde876a4964e606f85243 +0 -0
- data/test/dummy/tmp/cache/assets/D25/E10/sprockets%2F0633679c3d8859a3ecc9e058915fb8cc +0 -0
- data/test/dummy/tmp/cache/assets/D29/B30/sprockets%2F086d8d112d3fae3aa1442b0668c5ad14 +0 -0
- data/test/dummy/tmp/cache/assets/D2C/CE0/sprockets%2F41c51f756c28e2efb4df0f7993958d87 +0 -0
- data/test/dummy/tmp/cache/assets/D2F/C20/sprockets%2F048e618c1c32dba37a5ea17ce438d502 +0 -0
- data/test/dummy/tmp/cache/assets/D2F/E00/sprockets%2Ff58c01a5a367f623272bea14cb55ce05 +0 -0
- data/test/dummy/tmp/cache/assets/D32/0B0/sprockets%2Ff352d64df6333e4ec0a71a7e21a61a66 +0 -0
- data/test/dummy/tmp/cache/assets/D36/E60/sprockets%2F04b984b0c912e63e92b0fc5c7d03ea81 +0 -0
- data/test/dummy/tmp/cache/assets/D3E/040/sprockets%2F6f2e123d26b1b36e664bcf3b2a6d6788 +0 -0
- data/test/dummy/tmp/cache/assets/D48/7E0/sprockets%2F788b2cc322aa0075179f5fe78bfe418f +0 -0
- data/test/dummy/tmp/cache/assets/D48/810/sprockets%2F2f886557ed89d407ea37bc42104a8edb +0 -0
- data/test/dummy/tmp/cache/assets/D4D/240/sprockets%2Fb8cfde7355a79523ed7498afbb151582 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/770/sprockets%2F6f6fe0f4324f4edbd88f5a42623857d4 +0 -0
- data/test/dummy/tmp/cache/assets/D50/D00/sprockets%2F9b429fbca0ec669480440da7f9b49f58 +0 -0
- data/test/dummy/tmp/cache/assets/D51/8E0/sprockets%2F4eb588bf3b79d16661ddc1e82e19b785 +0 -0
- data/test/dummy/tmp/cache/assets/D58/A40/sprockets%2F1d4622f3a01c22f38abe6b16dd9b108c +0 -0
- data/test/dummy/tmp/cache/assets/D5E/9F0/sprockets%2F849e6398b6fef78228d4ae1476bbb68f +0 -0
- data/test/dummy/tmp/cache/assets/D5E/C40/sprockets%2F14a66c4429db00da5def52acb9553b24 +0 -0
- data/test/dummy/tmp/cache/assets/D60/530/sprockets%2F04148b8efa6507aab7e1c173d058cd2b +0 -0
- data/test/dummy/tmp/cache/assets/D66/1E0/sprockets%2F5436c5d00d9dbdb3f41c5934ac44dc28 +0 -0
- data/test/dummy/tmp/cache/assets/D68/690/sprockets%2Fad268c7a74b2827a1e39edd0c380a1d8 +0 -0
- data/test/dummy/tmp/cache/assets/D6F/3A0/sprockets%2F8eafb8f640b3fd1248b24ef9b395123b +0 -0
- data/test/dummy/tmp/cache/assets/D72/660/sprockets%2F5ab609853f2a56bfb77d91355f25cafa +0 -0
- data/test/dummy/tmp/cache/assets/D78/990/sprockets%2Fa03ef9a10faeef89a7553f42a56c6965 +0 -0
- data/test/dummy/tmp/cache/assets/D80/F70/sprockets%2Fee35c867a29403cfa596b66dae1e679e +0 -0
- data/test/dummy/tmp/cache/assets/D82/610/sprockets%2F2b7e0cb14ca5c5ba0af646a9a8212a62 +0 -0
- data/test/dummy/tmp/cache/assets/D84/2E0/sprockets%2F146ff2ff372fc6d9b99e85470dcb55b5 +0 -0
- data/test/dummy/tmp/cache/assets/D88/FD0/sprockets%2Fee9831bc4a19cc559d86fb59f3685ed3 +0 -0
- data/test/dummy/tmp/cache/assets/D89/2A0/sprockets%2F2701d66b84b6bd30870704bdbbcb3bdb +0 -0
- data/test/dummy/tmp/cache/assets/D89/FF0/sprockets%2F03603debeca1897d1df91a20a3bf04d4 +0 -0
- data/test/dummy/tmp/cache/assets/D92/A80/sprockets%2F18e700ec4beb52a7fbe3116acc81a587 +0 -0
- data/test/dummy/tmp/cache/assets/D96/3F0/sprockets%2Fd1dce00a1972457f8ab4cf4f80d1fa45 +0 -0
- data/test/dummy/tmp/cache/assets/D96/550/sprockets%2Fbe7c643b64ef13054ecbe92a4b49dd11 +0 -0
- data/test/dummy/tmp/cache/assets/D9B/FA0/sprockets%2F5f7d1fc42b1acc5ae00697e230ffc696 +0 -0
- data/test/dummy/tmp/cache/assets/D9C/D70/sprockets%2F05844ad9eb63fbd5b6b137dc36262ffa +0 -0
- data/test/dummy/tmp/cache/assets/D9D/540/sprockets%2Fc30d051cb4860b1be974cfebe6859d4c +0 -0
- data/test/dummy/tmp/cache/assets/D9E/F30/sprockets%2F7eb77a3cb0efd479c51aefc89e120063 +0 -0
- data/test/dummy/tmp/cache/assets/DA1/420/sprockets%2F2b2da3a86dabda8c701d709cb8758e96 +0 -0
- data/test/dummy/tmp/cache/assets/DA1/AC0/sprockets%2F8b88acb932b78e361cc6bd4c9d12ad54 +0 -0
- data/test/dummy/tmp/cache/assets/DA6/C10/sprockets%2Fc6a9fd3b81208eb5f88e0a57ccc7516e +0 -0
- data/test/dummy/tmp/cache/assets/DA7/220/sprockets%2F34f088fa6eec36f9074b9276b6c2cdba +0 -0
- data/test/dummy/tmp/cache/assets/DAF/0B0/sprockets%2F9ea457b3e62d559817eae1e1ec8fe1d9 +0 -0
- data/test/dummy/tmp/cache/assets/DB7/C10/sprockets%2Fb1cf68baf96448e9a2786bfddd6991e1 +0 -0
- data/test/dummy/tmp/cache/assets/DC8/720/sprockets%2Fbd6ffe7cca1ad4e420ca180c8184389c +0 -0
- data/test/dummy/tmp/cache/assets/DC8/C50/sprockets%2Ffe71f1c24f254c4deba3b8cedf104476 +0 -0
- data/test/dummy/tmp/cache/assets/DCB/2C0/sprockets%2F87fba1d32639cad1f2c4f8ea6b6a3f16 +0 -0
- data/test/dummy/tmp/cache/assets/DCF/7E0/sprockets%2F8f0f7d00b6add6cd869ca70ebf0d0982 +0 -0
- data/test/dummy/tmp/cache/assets/DDB/C20/sprockets%2F35ac8aeba03982a1ef7683d5fd8e7cf7 +0 -0
- data/test/dummy/tmp/cache/assets/DDF/750/sprockets%2F32ca08b9de9e9cdf19ae55458e8b42ee +0 -0
- data/test/dummy/tmp/cache/assets/DE5/3A0/sprockets%2Fe0ad18dbe1b892a31daa0c3a554d5d4d +0 -0
- data/test/dummy/tmp/cache/assets/E05/CA0/sprockets%2F0acaa4b251e9ee599e992fac3ff03fd7 +0 -0
- data/test/dummy/tmp/cache/assets/E07/510/sprockets%2F4da80e01edc5e7d06bf71ec9efe7c972 +0 -0
- data/test/dummy/tmp/cache/assets/E08/3C0/sprockets%2Fbe3ccf8c09dfcb94940bef68f50bc455 +0 -0
- data/test/dummy/tmp/cache/assets/E14/800/sprockets%2F8b99fef92144f5d13ff03b7ac6ffcfd9 +0 -0
- data/test/dummy/tmp/cache/assets/E1B/A70/sprockets%2F2c1ea98c0b1a8d2a08bd15f4ce8c3bdb +0 -0
- data/test/dummy/tmp/cache/assets/E1D/C00/sprockets%2Fa5c45a8a2adfd3de166440b053dfbfdc +0 -0
- data/test/dummy/tmp/cache/assets/E23/920/sprockets%2Feead0deffe21f3ccbe75290a0d16d293 +0 -0
- data/test/dummy/tmp/cache/assets/E24/550/sprockets%2Fa3e9ee903f73cbb1bfba82bf31a87ac3 +0 -0
- data/test/dummy/tmp/cache/assets/E25/410/sprockets%2F1dbf8e97f3ef6f4e5f89ae46d9b99a6b +0 -0
- data/test/dummy/tmp/cache/assets/E2B/AF0/sprockets%2Fd3d5b6ac573ee7e6ca20ed8c70ebfc16 +0 -0
- data/test/dummy/tmp/cache/assets/E2E/290/sprockets%2Fe5debdd1442851bacf83c3a5f1b98ffc +0 -0
- data/test/dummy/tmp/cache/assets/E32/4B0/sprockets%2F7998a29caeedcd612e6eb5baa3f4a5b7 +0 -0
- data/test/dummy/tmp/cache/assets/E33/210/sprockets%2F12b848beb52cbb5e9dedfd521d9a6c9e +0 -0
- data/test/dummy/tmp/cache/assets/E37/920/sprockets%2Fdecfac8e297916ee0fd0b3ac3ec9b478 +0 -0
- data/test/dummy/tmp/cache/assets/E47/EB0/sprockets%2F76ebce7bcd98e7b75ef79eec62bb9c31 +0 -0
- data/test/dummy/tmp/cache/assets/E56/230/sprockets%2F58da9342a714fbced3dd9cab5dae22bf +0 -0
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Yzc2MzJjMGI0ZDJkNDM1MTY5YTY4MjZkMGRhNGE4NzFhY2I2MGZkOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjQ2YzQ0ODgyOWNmYjk2ZjA2MjNlMTNlYjMyY2ZiZjZhZWJjZTBlMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTIxMzE2Y2QwNWFhMTI2MTlhZGE4NTA2YzIxMDBjYjViZWZjNGVkYzc2Y2Mw
|
10
|
+
MDE3NjMyMGJhOTg0OWQxM2I1YzU1NjFkMjE0YTI0MGM0MTk4N2Y1OWIwMWM3
|
11
|
+
YzI4YmE5MDUwMDUzYmI1MDFiY2VmZDg2NjIxMDQ2MmRhNWU2Y2I=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NDdhMjdiYjBjZWJmNWMyNDJiYTVhMzQxYzIxZjliMWRhMmNhZDgwMzFkMTZk
|
14
|
+
MzM0MWM5MjUyNjA3ZTRhOTVlMzdlYTVkNWU0NzBmNWMwZjNhOWQ1MDM4ZDAw
|
15
|
+
ZDRkZmU5NTY1YjQ5MjMyMjhkYjgxZjllZGM5YmE4NDFkOWE3Y2I=
|
@@ -12,20 +12,25 @@
|
|
12
12
|
//
|
13
13
|
//= require jquery
|
14
14
|
//= require jquery_ujs
|
15
|
+
//= require select2
|
15
16
|
//= require hubstats/bootstrap
|
16
17
|
//= require_tree .
|
17
18
|
|
18
19
|
|
19
|
-
|
20
|
+
$(document).ready( function() {
|
21
|
+
setTimespan()
|
22
|
+
});
|
23
|
+
|
24
|
+
function setTimespan() {
|
20
25
|
var index = readCookie("hubstats_index") || 2;
|
21
26
|
var timer = document.getElementById("time-select");
|
22
27
|
|
23
28
|
timer.selectedIndex = index;
|
24
29
|
|
25
30
|
timer.onchange = function() {
|
26
|
-
|
31
|
+
|
27
32
|
createCookie("hubstats_index",this.selectedIndex,1);
|
28
|
-
window.location
|
33
|
+
window.location.reload();
|
29
34
|
};
|
30
35
|
}
|
31
36
|
|
@@ -1,2 +1,161 @@
|
|
1
1
|
// Place all the behaviors and hooks related to the matching controller here.
|
2
2
|
// All this logic will automatically be available in application.js.
|
3
|
+
|
4
|
+
$(document).ready(function() {
|
5
|
+
queryParameters = getUrlVars();
|
6
|
+
setDefaults(queryParameters);
|
7
|
+
|
8
|
+
$("#state-group > .btn").on("click", function(){
|
9
|
+
updateQueryStringParameter(queryParameters,"state",$(this).attr('id'));
|
10
|
+
});
|
11
|
+
|
12
|
+
$("#sort-group > .btn").on("click", function(){
|
13
|
+
updateQueryStringParameter(queryParameters,"order",$(this).attr('id'));
|
14
|
+
});
|
15
|
+
|
16
|
+
$("#repos").change(function() {
|
17
|
+
var ids = $("#repos").val();
|
18
|
+
updateQueryStringParameter(queryParameters,"repos",ids);
|
19
|
+
});
|
20
|
+
|
21
|
+
$("#users").change(function() {
|
22
|
+
var ids = $("#users").val();
|
23
|
+
updateQueryStringParameter(queryParameters,"users",ids);
|
24
|
+
});
|
25
|
+
});
|
26
|
+
|
27
|
+
|
28
|
+
function updateQueryStringParameter(queryParameters, key, value) {
|
29
|
+
var uri = document.location.pathname;
|
30
|
+
if (!queryParameters[key])
|
31
|
+
queryParameters.push(key)
|
32
|
+
queryParameters[key] = value;
|
33
|
+
|
34
|
+
var i;
|
35
|
+
for (i = 0; i < queryParameters.length; i++) {
|
36
|
+
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
|
37
|
+
var value = queryParameters[i];
|
38
|
+
if (queryParameters[value].length >= 1)
|
39
|
+
uri = (uri + separator + value + '=' + queryParameters[value]);
|
40
|
+
}
|
41
|
+
|
42
|
+
document.location.href = uri
|
43
|
+
}
|
44
|
+
|
45
|
+
function getUrlVars() {
|
46
|
+
var vars = [], hash;
|
47
|
+
if (window.location.href.indexOf('?') > 0) {
|
48
|
+
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
49
|
+
|
50
|
+
for (var i = 0; i < hashes.length; i++) {
|
51
|
+
hash = hashes[i].split('=');
|
52
|
+
vars.push(hash[0]);
|
53
|
+
vars[hash[0]] = hash[1];
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
return vars;
|
58
|
+
}
|
59
|
+
|
60
|
+
function setDefaults(queryParameters) {
|
61
|
+
if (queryParameters["state"])
|
62
|
+
$('#' + queryParameters["state"]).addClass('active');
|
63
|
+
else
|
64
|
+
$('#all').addClass('active');
|
65
|
+
|
66
|
+
if (queryParameters["order"])
|
67
|
+
$('#' + queryParameters["order"]).addClass('active');
|
68
|
+
else
|
69
|
+
$('#desc').addClass('active');
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
$(document).ready(function() {
|
75
|
+
usersIDs = queryParameters["users"] ? queryParameters["users"].replace("%2C", ",") : "";
|
76
|
+
reposIDs = queryParameters["repos"] ? queryParameters["repos"].replace("%2C", ",") : "";
|
77
|
+
|
78
|
+
$("#repos").select2({
|
79
|
+
placeholder: "Repositories",
|
80
|
+
multiple: true,
|
81
|
+
ajax: {
|
82
|
+
url: "./repos",
|
83
|
+
dataType: 'json',
|
84
|
+
quietMillis: 100,
|
85
|
+
data: function (term) {
|
86
|
+
return {
|
87
|
+
query: term
|
88
|
+
};
|
89
|
+
},
|
90
|
+
results: function (data) {
|
91
|
+
return {
|
92
|
+
results: $.map(data, function (repo) {
|
93
|
+
return {
|
94
|
+
text: repo.name,
|
95
|
+
id: repo.id
|
96
|
+
}
|
97
|
+
})
|
98
|
+
};
|
99
|
+
}
|
100
|
+
},
|
101
|
+
initSelection: function(element, callback) {
|
102
|
+
if (reposIDs !== "") {
|
103
|
+
$.ajax("./repos", {
|
104
|
+
data: { id: reposIDs },
|
105
|
+
dataType: "json"
|
106
|
+
}).done(function (data) { callback(
|
107
|
+
$.map(data, function (repo) {
|
108
|
+
return {
|
109
|
+
text: repo.name,
|
110
|
+
id: repo.id
|
111
|
+
}
|
112
|
+
})
|
113
|
+
);
|
114
|
+
});
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}).select2('val', []);
|
118
|
+
|
119
|
+
|
120
|
+
$("#users").select2({
|
121
|
+
placeholder: "Users",
|
122
|
+
multiple: true,
|
123
|
+
ajax: {
|
124
|
+
url: "./users",
|
125
|
+
dataType: 'json',
|
126
|
+
quietMillis: 100,
|
127
|
+
data: function (term) {
|
128
|
+
return {
|
129
|
+
query: term
|
130
|
+
};
|
131
|
+
},
|
132
|
+
results: function (data) {
|
133
|
+
return {
|
134
|
+
results: $.map(data, function (user) {
|
135
|
+
return {
|
136
|
+
text: user.login,
|
137
|
+
id: user.id
|
138
|
+
}
|
139
|
+
})
|
140
|
+
};
|
141
|
+
}
|
142
|
+
},
|
143
|
+
initSelection: function(element, callback) {
|
144
|
+
if (usersIDs !== "") {
|
145
|
+
$.ajax("./users", {
|
146
|
+
data: { id: usersIDs },
|
147
|
+
dataType: "json"
|
148
|
+
}).done(function (data) { callback(
|
149
|
+
$.map(data, function (user) {
|
150
|
+
return {
|
151
|
+
text: user.login,
|
152
|
+
id: user.id
|
153
|
+
}
|
154
|
+
})
|
155
|
+
);
|
156
|
+
});
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}).select2('val', []);
|
160
|
+
|
161
|
+
});
|
@@ -10,6 +10,8 @@
|
|
10
10
|
*
|
11
11
|
*= require_self
|
12
12
|
*= require hubstats/bootstrap
|
13
|
+
*= require select2
|
14
|
+
*= require select2-bootstrap
|
13
15
|
*= require_tree .
|
14
16
|
*/
|
15
17
|
|
@@ -24,4 +26,49 @@
|
|
24
26
|
|
25
27
|
#header .title {
|
26
28
|
font-size: 28px;
|
29
|
+
}
|
30
|
+
|
31
|
+
.single-comment > .user-image, .single-pull > .user-image {
|
32
|
+
padding: 5px;
|
33
|
+
}
|
34
|
+
|
35
|
+
.user-image > img{
|
36
|
+
width: 55px;
|
37
|
+
height: 55px;
|
38
|
+
}
|
39
|
+
|
40
|
+
.pulls, .comments {
|
41
|
+
margin: 15px 0px 15px 0px;
|
42
|
+
border: 1px solid #ccc;
|
43
|
+
border-radius: 5px;
|
44
|
+
}
|
45
|
+
|
46
|
+
.pulls > .col, .comments > .col {
|
47
|
+
padding: 0px 5px 0px 5px;
|
48
|
+
}
|
49
|
+
|
50
|
+
.row .single-pull, .row .single-comment {
|
51
|
+
padding:5px;
|
52
|
+
margin: 0px;
|
53
|
+
border-bottom: 1px solid #ccc;
|
54
|
+
}
|
55
|
+
|
56
|
+
.comment-info > .well {
|
57
|
+
padding: 10px;
|
58
|
+
margin-bottom: 5px;
|
59
|
+
}
|
60
|
+
|
61
|
+
.single-pull > .pull-info {
|
62
|
+
padding: 0px;
|
63
|
+
}
|
64
|
+
.pull-info > h4 {
|
65
|
+
margin: 0px;
|
66
|
+
}
|
67
|
+
|
68
|
+
.push-down {
|
69
|
+
margin-top: 8px;
|
70
|
+
}
|
71
|
+
|
72
|
+
.push-down-farther {
|
73
|
+
margin-top: 15px;
|
27
74
|
}
|
@@ -4,16 +4,33 @@ module Hubstats
|
|
4
4
|
class PullRequestsController < ApplicationController
|
5
5
|
|
6
6
|
def index
|
7
|
+
@pull_requests = Hubstats::PullRequest.includes(:user).includes(:repo)
|
8
|
+
.belonging_to_users(params[:users])
|
9
|
+
.belonging_to_repos(params[:repos])
|
10
|
+
.with_state(params[:state])
|
11
|
+
.state_based_order(@timespan,params[:state],params[:order])
|
12
|
+
.paginate(:page => params[:page], :per_page => 15)
|
13
|
+
|
14
|
+
@labels = Hubstats::Label.with_a_pull_request
|
15
|
+
end
|
16
|
+
|
17
|
+
def repo_index
|
7
18
|
@repo = Hubstats::Repo.where(name: params[:repo]).first
|
8
|
-
@pull_requests = Hubstats::PullRequest.belonging_to_repo(@repo.id).closed_since(@timespan)
|
19
|
+
@pull_requests = Hubstats::PullRequest.belonging_to_repo(@repo.id).closed_since(@timespan).order("closed_at DESC")
|
9
20
|
end
|
10
21
|
|
11
22
|
def show
|
12
23
|
@repo = Hubstats::Repo.where(name: params[:repo]).first
|
13
24
|
@pull_request = Hubstats::PullRequest.belonging_to_repo(@repo.id).where(id: params[:id]).first
|
14
25
|
@comments = Hubstats::Comment.belonging_to_pull_request(params[:id]).includes(:user).created_since(@timespan)
|
26
|
+
@stats = {
|
27
|
+
github: @pull_request.html_url,
|
28
|
+
comment_count: @comments.count(:all),
|
29
|
+
additions: @pull_request.additions.to_i,
|
30
|
+
deletions: @pull_request.deletions.to_i,
|
31
|
+
net_additions: @pull_request.additions.to_i - @pull_request.deletions.to_i
|
32
|
+
}
|
15
33
|
end
|
16
34
|
|
17
35
|
end
|
18
|
-
|
19
36
|
end
|
@@ -2,17 +2,20 @@ require_dependency "hubstats/application_controller"
|
|
2
2
|
|
3
3
|
module Hubstats
|
4
4
|
class ReposController < ApplicationController
|
5
|
+
|
5
6
|
def index
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
if params[:query]
|
8
|
+
@repos = Hubstats::Repo.where("name LIKE ?", "%#{params[:query]}%").order("name ASC")
|
9
|
+
elsif params[:id]
|
10
|
+
@repos = Hubstats::Repo.where(id: params[:id].split(",")).order("name ASC")
|
11
|
+
else
|
12
|
+
@repos = Hubstats::Repo.with_recent_activity(@timespan)
|
13
|
+
end
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.html # show.html.erb
|
17
|
+
format.json { render :json => @repos}
|
18
|
+
end
|
16
19
|
end
|
17
20
|
|
18
21
|
def show
|
@@ -28,5 +31,19 @@ module Hubstats
|
|
28
31
|
net_additions: Hubstats::PullRequest.closed_since(@timespan).belonging_to_repo(@repo.id).sum(:additions).to_i - Hubstats::PullRequest.closed_since(@timespan).belonging_to_repo(@repo.id).sum(:deletions).to_i
|
29
32
|
}
|
30
33
|
end
|
34
|
+
|
35
|
+
def dashboard
|
36
|
+
@repos = Hubstats::Repo.with_recent_activity(@timespan).limit(20)
|
37
|
+
@users = Hubstats::User.with_pulls_or_comments(@timespan).only_active.limit(20)
|
38
|
+
@repo_count = Hubstats::Repo.with_recent_activity(@timespan).count(:all)
|
39
|
+
@user_count = Hubstats::User.with_pulls_or_comments(@timespan).only_active.length
|
40
|
+
@stats = {
|
41
|
+
user_count: @user_count,
|
42
|
+
pull_count: Hubstats::PullRequest.closed_since(@timespan).count(:all),
|
43
|
+
comment_count: Hubstats::Comment.created_since(@timespan).count(:all),
|
44
|
+
avg_additions: Hubstats::PullRequest.closed_since(@timespan).average(:additions).to_i,
|
45
|
+
avg_deletions: Hubstats::PullRequest.closed_since(@timespan).average(:deletions).to_i
|
46
|
+
}
|
47
|
+
end
|
31
48
|
end
|
32
49
|
end
|
@@ -4,7 +4,18 @@ module Hubstats
|
|
4
4
|
class UsersController < ApplicationController
|
5
5
|
|
6
6
|
def index
|
7
|
-
|
7
|
+
if params[:query]
|
8
|
+
@users = Hubstats::User.where("login LIKE ?", "%#{params[:query]}%").order("login ASC")
|
9
|
+
elsif params[:id]
|
10
|
+
@users = Hubstats::User.where(id: params[:id].split(",")).order("login ASC")
|
11
|
+
else
|
12
|
+
@users = Hubstats::User.with_pulls_or_comments(@timespan)
|
13
|
+
end
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.html # index.html.erb
|
17
|
+
format.json { render :json => @users}
|
18
|
+
end
|
8
19
|
end
|
9
20
|
|
10
21
|
def show
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hubstats
|
2
|
+
class Label < ActiveRecord::Base
|
3
|
+
scope :with_a_pull_request, lambda {
|
4
|
+
select("hubstats_labels.*")
|
5
|
+
.select("COUNT(hubstats_labels_pull_requests.pull_request_id) AS pull_request_count")
|
6
|
+
.joins("LEFT JOIN hubstats_labels_pull_requests ON hubstats_labels_pull_requests.label_id = hubstats_labels.id")
|
7
|
+
.having("pull_request_count > 0")
|
8
|
+
.group("hubstats_labels.id")
|
9
|
+
}
|
10
|
+
|
11
|
+
attr_accessible :url, :name, :color
|
12
|
+
|
13
|
+
has_and_belongs_to_many :pull_requests, :join_table => 'hubstats_labels_pull_requests'
|
14
|
+
end
|
15
|
+
end
|
@@ -1,32 +1,54 @@
|
|
1
1
|
module Hubstats
|
2
2
|
class PullRequest < ActiveRecord::Base
|
3
3
|
|
4
|
-
scope :closed_since, lambda {|time| where("closed_at > ?", time)
|
4
|
+
scope :closed_since, lambda {|time| where("closed_at > ?", time) }
|
5
|
+
scope :updated_since, lambda {|time| where("updated_at > ?", time) }
|
6
|
+
scope :opened_since, lambda {|time| where("created_at > ?", time) }
|
5
7
|
scope :belonging_to_repo, lambda {|repo_id| where(repo_id: repo_id)}
|
6
8
|
scope :belonging_to_user, lambda {|user_id| where(user_id: user_id)}
|
7
|
-
|
9
|
+
scope :belonging_to_repos, lambda {|repo_id| where(repo_id: repo_id.split(',')) if repo_id}
|
10
|
+
scope :belonging_to_users, lambda {|user_id| where(user_id: user_id.split(',')) if user_id}
|
11
|
+
scope :with_state, lambda {|state| (where(state: state) unless state == 'all') if state}
|
12
|
+
|
8
13
|
attr_accessible :id, :url, :html_url, :diff_url, :patch_url, :issue_url, :commits_url,
|
9
14
|
:review_comments_url, :review_comment_url, :comments_url, :statuses_url, :number,
|
10
15
|
:state, :title, :body, :created_at, :updated_at, :closed_at, :merged_at,
|
11
16
|
:merge_commit_sha, :merged, :mergeable, :comments, :commits, :additions,
|
12
17
|
:deletions, :changed_files, :user_id, :repo_id
|
13
18
|
|
14
|
-
|
15
|
-
|
19
|
+
belongs_to :user
|
20
|
+
belongs_to :repo
|
21
|
+
has_and_belongs_to_many :labels, :join_table => 'hubstats_labels_pull_requests'
|
22
|
+
|
23
|
+
def self.create_or_update(github_pull)
|
24
|
+
github_pull = github_pull.to_h if github_pull.respond_to? :to_h
|
25
|
+
|
26
|
+
user = Hubstats::User.create_or_update(github_pull[:user])
|
27
|
+
github_pull[:user_id] = user.id
|
28
|
+
repo = Hubstats::Repo.create_or_update(github_pull[:repository])
|
29
|
+
github_pull[:repo_id] = repo.id
|
16
30
|
|
17
|
-
|
18
|
-
github_pull = github_pull.to_h if github_pull.respond_to? :to_h
|
31
|
+
pull_data = github_pull.slice(*column_names.map(&:to_sym))
|
19
32
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
33
|
+
pull = where(:id => pull_data[:id]).first_or_create(pull_data)
|
34
|
+
return pull if pull.update_attributes(pull_data)
|
35
|
+
Rails.logger.debug pull.errors.inspect
|
36
|
+
end
|
24
37
|
|
25
|
-
|
38
|
+
def add_labels(labels)
|
39
|
+
labels.map!{|v| Hubstats::Label.where(name: v.name).first}
|
40
|
+
self.labels = labels
|
41
|
+
end
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
|
43
|
+
def self.state_based_order(timespan,state,order)
|
44
|
+
order = ["ASC","DESC"].detect{|order_type| order_type.to_s == order.to_s.upcase } || "DESC"
|
45
|
+
|
46
|
+
if state == "closed"
|
47
|
+
closed_since(timespan).order("closed_at #{order}")
|
48
|
+
else
|
49
|
+
opened_since(timespan).order("created_at #{order}")
|
30
50
|
end
|
51
|
+
end
|
52
|
+
|
31
53
|
end
|
32
54
|
end
|