From: Alex Sadleir Date: Sat, 19 Jan 2013 13:11:26 +0000 Subject: group by category X-Git-Url: https://maxious.lambdacomplex.org/git/?p=scannr.git&a=commitdiff&h=7f656084c6c96fca04e8576ae1f88afcee20a5d0 --- group by category --- --- a/.idea/sqldialects.xml +++ /dev/null @@ -1,8 +1,1 @@ - - - - - - - --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,21 +2,49 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + - - + + - - - - - - + + - - + + - - - - - + + - - + + - + + + + + + + + + + + + + + + + + + + @@ -128,21 +167,20 @@ - @@ -170,6 +208,8 @@ + + @@ -188,34 +228,18 @@ - - - - - - - - - - - + + + + - - - + + + + + + + + @@ -271,28 +317,28 @@ - - + + - + + + + - - - - + + + + - - + + + - - - - @@ -355,11 +401,26 @@ + + + + + + + + + + + + + + + @@ -380,74 +441,53 @@ + + + + + + + + + + - - - - - - - - - - - - - + + + - - - + + + - + - - - + + + - - - - - - - - - - - - - + + + - - - - - - - - - - - --- /dev/null +++ b/README.md @@ -1,1 +1,64 @@ +# [HTML5 Boilerplate](http://html5boilerplate.com) +HTML5 Boilerplate is a professional front-end template for building fast, +robust, and adaptable web apps or sites. + +This project is the product of many years of iterative development and combined +community knowledge. It does not impose a specific development philosophy or +framework, so you're free to architect your code in the way that you want. + +* Source: [https://github.com/h5bp/html5-boilerplate](https://github.com/h5bp/html5-boilerplate) +* Homepage: [http://html5boilerplate.com](http://html5boilerplate.com) +* Twitter: [@h5bp](http://twitter.com/h5bp) + + +## Quick start + +Choose one of the following options: + +1. Download the latest stable release from + [html5boilerplate.com](http://html5boilerplate.com/) or a custom build from + [Initializr](http://www.initializr.com). +2. Clone the git repo — `git clone + https://github.com/h5bp/html5-boilerplate.git` - and checkout the tagged + release you'd like to use. + + +## Features + +* HTML5 ready. Use the new elements with confidence. +* Cross-browser compatible (Chrome, Opera, Safari, Firefox 3.6+, IE6+). +* Designed with progressive enhancement in mind. +* Includes [Normalize.css](http://necolas.github.com/normalize.css/) for CSS + normalizations and common bug fixes. +* The latest [jQuery](http://jquery.com/) via CDN, with a local fallback. +* The latest [Modernizr](http://modernizr.com/) build for feature detection. +* IE-specific classes for easier cross-browser control. +* Placeholder CSS Media Queries. +* Useful CSS helpers. +* Default print CSS, performance optimized. +* Protection against any stray `console.log` causing JavaScript errors in + IE6/7. +* An optimized Google Analytics snippet. +* Apache server caching, compression, and other configuration defaults for + Grade-A performance. +* Cross-domain Ajax and Flash. +* "Delete-key friendly." Easy to strip out parts you don't need. +* Extensive inline and accompanying documentation. + + +## Documentation + +Take a look at the [documentation table of +contents](/h5bp/html5-boilerplate/blob/master/doc/README.md). This +documentation is bundled with the project, which makes it readily available for +offline reading and provides a useful starting point for any documentation +you want to write about your project. + + +## Contributing + +Anyone and everyone is welcome to +[contribute](/h5bp/html5-boilerplate/blob/master/doc/contribute.md). Hundreds +of developers have helped make the HTML5 Boilerplate what it is today. + --- /dev/null +++ b/README.txt @@ -1,1 +1,1 @@ - +ffmpeg from http://ffmpeg.zeranoe.com/builds/ --- a/common.inc.php +++ b/common.inc.php @@ -57,20 +57,12 @@ - - - - - - - - - - - - -
- -
-
-
- -
-
-
- -
-
-
- -
- - - - - - - - - - - - - - - - - --- a/db.sql +++ b/db.sql @@ -92,22 +92,4 @@ -- PostgreSQL database dump complete -- -CREATE TABLE "compilation" ( - "filename" text NOT NULL, - "files" text ARRAY NOT NULL, - "datetime" timestamp NOT NULL -); -CREATE TABLE "trunk_log" ( - "id" text NOT NULL, - "datetime" integer NOT NULL, - "site" integer NOT NULL, - "action" text NOT NULL, - "sourcetype" character(1) NOT NULL, - "sourceid" smallint NOT NULL, - "targettype" character(1) NOT NULL, - "targetid" smallint NOT NULL, - "channel" smallint NOT NULL, - "calltype" text NOT NULL -); - --- /dev/null +++ b/generateConvos.php @@ -1,1 +1,36 @@ +prepare('select * from recordings limit 100;'); +$sth->execute(); +$recordings = $sth->fetchAll(); +$convos = Array(); +$convo = Array(); +foreach ($recordings as $i => $recording) { + + if (count($convo) > 0) { + echo "
" . strcasecmp($convos[count($convos) - 1][0]['call_timestamp'], $recording['call_timestamp']); + if (abs(strcasecmp($convos[count($convos) - 1][0]['call_timestamp'], $recording['call_timestamp'])) > 2) { + echo " " . $convos[count($convos) - 1][0]['call_timestamp'] . " " . $recording['call_timestamp']; + } + if (strcasecmp($convos[count($convos) - 1][0]['tgid'], $recording['tgid']) != 0) { + $convos[] = $convo; + $convo = Array(); + } + } + ; + //print_r($recording); + $convo[] = $recording; + //print_r($convo); + //echo "
\n"; +} +foreach ($convos as $i => $convo) { + foreach ($convo as $recording) { + echo $recording['filename'] . " , "; + } + echo "

\n"; +} +?> + + --- a/generateHourlys.php +++ b/generateHourlys.php @@ -1,7 +1,7 @@ prepare("select tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by tgid, ahour, aday order by aday DESC, ahour, tgid;"); -// TODO use tgid categories instead, tgid too specific +/*$sth = $conn->prepare("select tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, +count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by tgid, ahour, aday order by aday DESC, ahour, tgid;"); + $sth->execute(); $hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); foreach($hourlies as $hourly) { processHourly($hourly); } -$sth = $conn->prepare("select 'hour' as tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by ahour, aday order by aday DESC, ahour;"); +$sth = $conn->prepare("select 'hour' as tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, +count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by ahour, aday order by aday DESC, ahour;"); + +$sth->execute(); +$hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); +foreach($hourlies as $hourly) { + processHourly($hourly); +} +*/ +$sth = $conn->prepare("select coalesce(category,'unknown') as tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, +count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames +from recordings inner join tgids on recordings.tgid = tgids.tgid group by category, ahour, aday order by aday DESC, ahour, category;"); $sth->execute(); $hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); @@ -40,5 +44,3 @@ } -// delete uninteresting compilations - --- /dev/null +++ b/inserttgid.txt @@ -1,1 +1,2 @@ +insert into tgids (tgid,alpha_tag) (SELECT distinct tgid, tgname as alpha_tag FROM recordings WHERE NOT EXISTS (SELECT tgid FROM tgids WHERE tgid=recordings.tgid)); --- a/js/daterangepicker.js +++ /dev/null @@ -1,609 +1,1 @@ -/** -* @version: 1.0.1 -* @author: Dan Grossman http://www.dangrossman.info/ -* @date: 2012-08-20 -* @copyright: Copyright (c) 2012 Dan Grossman. All rights reserved. -* @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0 -* @website: http://www.improvely.com/ -*/ -!function ($) { - var DateRangePicker = function (element, options, cb) { - var hasOptions = typeof options == 'object' - var localeObject; - - //state - this.startDate = Date.create('today'); - this.endDate = Date.create('today'); - this.minDate = false; - this.maxDate = false; - this.changed = false; - this.cleared = false; - this.ranges = {}; - this.opens = 'right'; - this.cb = function () { }; - this.format = '{MM}/{dd}/{yyyy}'; - this.separator = ' - '; - this.showWeekNumbers = false; - this.buttonClasses = ['btn-success']; - this.locale = { - applyLabel: 'Apply', - clearLabel:"Clear", - fromLabel: 'From', - toLabel: 'To', - weekLabel: 'W', - customRangeLabel: 'Custom Range', - daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr','Sa'], - monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - firstDay: 0 - }; - - localeObject = this.locale; - - this.leftCalendar = { - month: Date.create('today').set({ day: 1, month: this.startDate.getMonth(), year: this.startDate.getFullYear() }), - calendar: Array() - }; - - this.rightCalendar = { - month: Date.create('today').set({ day: 1, month: this.endDate.getMonth(), year: this.endDate.getFullYear() }), - calendar: Array() - }; - - //element that triggered the date range picker - this.element = $(element); - - if (this.element.hasClass('pull-right')) - this.opens = 'left'; - - if (this.element.is('input')) { - this.element.on({ - click: $.proxy(this.show, this), - focus: $.proxy(this.show, this) - }); - } else { - this.element.on('click', $.proxy(this.show, this)); - } - - if (hasOptions) { - if(typeof options.locale == 'object') { - $.each(localeObject, function (property, value) { - localeObject[property] = options.locale[property] || value; - }); - } - } - - var DRPTemplate = ''; - - this.container = $(DRPTemplate).appendTo('body'); - - if (hasOptions) { - - if (typeof options.format == 'string') - this.format = options.format; - - if (typeof options.separator == 'string') - this.separator = options.separator; - - if (typeof options.startDate == 'string') - this.startDate = Date.create(options.startDate); - - if (typeof options.endDate == 'string') - this.endDate = Date.create(options.endDate); - - if (typeof options.minDate == 'string') - this.minDate = Date.create(options.minDate); - - if (typeof options.maxDate == 'string') - this.maxDate = Date.create(options.maxDate); - - - if (typeof options.startDate == 'object') - this.startDate = options.startDate; - - if (typeof options.endDate == 'object') - this.endDate = options.endDate; - - if (typeof options.minDate == 'object') - this.minDate = options.minDate; - - if (typeof options.maxDate == 'object') - this.maxDate = options.maxDate; - - if (typeof options.ranges == 'object') { - for (var range in options.ranges) { - - var start = options.ranges[range][0]; - var end = options.ranges[range][1]; - - if (typeof start == 'string') - start = Date.create(start); - - if (typeof end == 'string') - end = Date.create(end); - - // If we have a min/max date set, bound this range - // to it, but only if it would otherwise fall - // outside of the min/max. - if (this.minDate && start < this.minDate) - start = this.minDate; - - if (this.maxDate && end > this.maxDate) - end = this.maxDate; - - // If the end of the range is before the minimum (if min is set) OR - // the start of the range is after the max (also if set) don't display this - // range option. - if ((this.minDate && end < this.minDate) || (this.maxDate && start > this.maxDate)) - { - continue; - } - - this.ranges[range] = [start, end]; - } - - var list = '
    '; - for (var range in this.ranges) { - list += '
  • ' + range + '
  • '; - } - list += '
  • ' + this.locale.customRangeLabel + '
  • '; - list += '
'; - this.container.find('.ranges').prepend(list); - } - - // update day names order to firstDay - if (typeof options.locale == 'object') { - if (typeof options.locale.firstDay == 'number') { - this.locale.firstDay = options.locale.firstDay; - var iterator = options.locale.firstDay; - while (iterator > 0) { - this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); - iterator--; - } - } - } - - if (typeof options.opens == 'string') - this.opens = options.opens; - - if (typeof options.showWeekNumbers == 'boolean') { - this.showWeekNumbers = options.showWeekNumbers; - } - - if (typeof options.buttonClasses == 'string') { - this.buttonClasses = [options.buttonClasses]; - } - - if (typeof options.buttonClasses == 'object') { - this.buttonClasses = options.buttonClasses; - } - - } - - //apply CSS classes to buttons - var c = this.container; - $.each(this.buttonClasses, function (idx, val) { - c.find('button').addClass(val); - }); - - if (this.opens == 'right') { - //swap calendar positions - var left = this.container.find('.calendar.left'); - var right = this.container.find('.calendar.right'); - left.removeClass('left').addClass('right'); - right.removeClass('right').addClass('left'); - } - - if (typeof options == 'undefined' || typeof options.ranges == 'undefined') - this.container.find('.calendar').show(); - - if (typeof cb == 'function') - this.cb = cb; - - this.container.addClass('opens' + this.opens); - - //event listeners - this.container.on('mousedown', $.proxy(this.mousedown, this)); - this.container.find('.calendar').on('click', '.prev', $.proxy(this.clickPrev, this)); - this.container.find('.calendar').on('click', '.next', $.proxy(this.clickNext, this)); - this.container.find('.ranges').on('click', 'button.applyBtn', $.proxy(this.clickApply, this)); - this.container.find('.ranges').on('click', 'button.clearBtn', $.proxy(this.clickClear, this)); - - this.container.find('.calendar').on('click', 'td.available', $.proxy(this.clickDate, this)); - this.container.find('.calendar').on('mouseenter', 'td.available', $.proxy(this.enterDate, this)); - this.container.find('.calendar').on('mouseleave', 'td.available', $.proxy(this.updateView, this)); - - this.container.find('.ranges').on('click', 'li', $.proxy(this.clickRange, this)); - this.container.find('.ranges').on('mouseenter', 'li', $.proxy(this.enterRange, this)); - this.container.find('.ranges').on('mouseleave', 'li', $.proxy(this.updateView, this)); - - this.element.on('keyup', $.proxy(this.updateFromControl, this)); - - this.updateView(); - this.updateCalendars(); - - }; - - DateRangePicker.prototype = { - - constructor: DateRangePicker, - - mousedown: function (e) { - e.stopPropagation(); - e.preventDefault(); - }, - - updateView: function () { - this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); - this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); - - this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format)); - this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format)); - - if (this.startDate.is(this.endDate) || this.startDate.isBefore(this.endDate)) { - this.container.find('button.applyBtn').removeAttr('disabled'); - } else { - this.container.find('button.applyBtn').attr('disabled', 'disabled'); - } - }, - - updateFromControl: function () { - if (!this.element.is('input')) return; - - var dateString = this.element.val().split(this.separator); - var start = Date.create(dateString[0]); - var end = Date.create(dateString[1]); - - if (start == null || end == null) return; - if (end.isBefore(start)) return; - - this.startDate = start; - this.endDate = end; - - this.updateView(); - this.cb(this.startDate, this.endDate); - this.updateCalendars(); - }, - - notify: function () { - if (!this.cleared) { - this.updateView(); - } - - if (this.element.is('input')) { - this.element.val(this.cleared ? '' : this.startDate.format(this.format) + this.separator + this.endDate.format(this.format)); - } - var arg1 = (this.cleared ? null : this.startDate), - arg2 = (this.cleared ? null : this.endDate); - this.cleared = false; - this.cb(arg1,arg2); - }, - - move: function () { - if (this.opens == 'left') { - this.container.css({ - top: this.element.offset().top + this.element.outerHeight(), - right: $(window).width() - this.element.offset().left - this.element.outerWidth(), - left: 'auto' - }); - } else { - this.container.css({ - top: this.element.offset().top + this.element.outerHeight(), - left: this.element.offset().left, - right: 'auto' - }); - } - }, - - show: function (e) { - this.container.show(); - this.move(); - - if (e) { - e.stopPropagation(); - e.preventDefault(); - } - - this.changed = false; - - this.element.trigger('shown',{target:e.target,picker:this}); - - $(document).on('mousedown', $.proxy(this.hide, this)); - }, - - hide: function (e) { - this.container.hide(); - $(document).off('mousedown', this.hide); - - if (this.changed) { - this.changed = false; - this.notify(); - } - }, - - enterRange: function (e) { - var label = e.target.innerHTML; - if (label == this.locale.customRangeLabel) { - this.updateView(); - } else { - var dates = this.ranges[label]; - this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format)); - this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format)); - } - }, - - clickRange: function (e) { - var label = e.target.innerHTML; - if (label == this.locale.customRangeLabel) { - this.container.find('.calendar').show(); - } else { - var dates = this.ranges[label]; - - this.startDate = dates[0]; - this.endDate = dates[1]; - - this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); - this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); - this.updateCalendars(); - - this.changed = true; - - this.container.find('.calendar').hide(); - this.hide(); - } - }, - - clickPrev: function (e) { - var cal = $(e.target).parents('.calendar'); - if (cal.hasClass('left')) { - this.leftCalendar.month.addMonths(-1); - } else { - this.rightCalendar.month.addMonths(-1); - } - this.updateCalendars(); - }, - - clickNext: function (e) { - var cal = $(e.target).parents('.calendar'); - if (cal.hasClass('left')) { - this.leftCalendar.month.addMonths(1); - } else { - this.rightCalendar.month.addMonths(1); - } - this.updateCalendars(); - }, - - enterDate: function (e) { - - var title = $(e.target).attr('title'); - var row = title.substr(1, 1); - var col = title.substr(3, 1); - var cal = $(e.target).parents('.calendar'); - - if (cal.hasClass('left')) { - this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format)); - } else { - this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format)); - } - - }, - - clickDate: function (e) { - var title = $(e.target).attr('title'); - var row = title.substr(1, 1); - var col = title.substr(3, 1); - var cal = $(e.target).parents('.calendar'); - - if (cal.hasClass('left')) { - startDate = this.leftCalendar.calendar[row][col]; - endDate = this.endDate; - this.element.trigger('clicked',{ - dir: 'left', - picker: this - }); - } else { - startDate = this.startDate; - endDate = this.rightCalendar.calendar[row][col]; - this.element.trigger('clicked',{ - dir: 'right', - picker: this - }); - } - - cal.find('td').removeClass('active'); - - if (startDate.is(endDate) || startDate.isBefore(endDate)) { - $(e.target).addClass('active'); - if (!startDate.is(this.startDate) || !endDate.is(this.endDate)) - this.changed = true; - this.startDate = startDate; - this.endDate = endDate; - } - else if (startDate.isAfter(endDate)) { - $(e.target).addClass('active'); - this.changed = true; - this.startDate = startDate; - this.endDate = startDate.clone().addDays(1); - } - - this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); - this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); - this.updateCalendars(); - }, - - clickApply: function (e) { - this.hide(); - }, - - clickClear: function (e) { - this.changed = true; - this.cleared = true; - this.hide(); - }, - - updateCalendars: function () { - this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.getMonth(), this.leftCalendar.month.getFullYear()); - this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.getMonth(), this.rightCalendar.month.getFullYear()); - this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate)); - this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.startDate, this.maxDate)); - this.element.trigger('updated',this); - }, - - buildCalendar: function (month, year) { - - var firstDay = Date.create('today').set({ day: 1, month: month, year: year }); - var lastMonth = firstDay.clone().addDays(-1).getMonth(); - var lastYear = firstDay.clone().addDays(-1).getFullYear(); - - var daysInMonth = this.getDaysInMonth(year, month); - var daysInLastMonth = this.getDaysInMonth(lastYear, lastMonth); - - var dayOfWeek = firstDay.getDay(); - - //initialize a 6 rows x 7 columns array for the calendar - var calendar = Array(); - for (var i = 0; i < 6; i++) { - calendar[i] = Array(); - } - - //populate the calendar with date objects - var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; - if (startDay > daysInLastMonth) - startDay -= 7; - - if (dayOfWeek == this.locale.firstDay) - startDay = daysInLastMonth - 6; - - var curDate = Date.create('today').set({ day: startDay, month: lastMonth, year: lastYear }); - for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = curDate.clone().addDays(1)) { - if (i > 0 && col % 7 == 0) { - col = 0; - row++; - } - calendar[row][col] = curDate; - } - - return calendar; - - }, - - renderCalendar: function (calendar, selected, minDate, maxDate) { - var html = ''; - html += ''; - html += ''; - - // add empty cell for week number - if (this.showWeekNumbers) - html += ''; - - if (!minDate || minDate < calendar[1][1]) - { - html += ''; - } - else - { - html += ''; - } - html += ''; - if (!maxDate || maxDate
' + this.locale.monthNames[calendar[1][1].getMonth()] + calendar[1][1].format(' {yyyy}') + '