├── LICENSE
├── README.md
├── build.as3
├── build.xml
├── build
├── build.properties
├── common.properties
├── doc
│ ├── package.description.xml
│ └── templates
│ │ ├── AC_OETags.js
│ │ ├── ASDoc_Config_Base.xml
│ │ ├── ASDoc_terms.xml
│ │ ├── ClassHeader.xslt
│ │ ├── Classes.xslt
│ │ ├── Overviews_Base.xml
│ │ ├── PostProcessing.xslt
│ │ ├── all-classes.xslt
│ │ ├── all-index.xslt
│ │ ├── asdoc-util.xslt
│ │ ├── asdoc.js
│ │ ├── class-files.xslt
│ │ ├── class-list.xslt
│ │ ├── class-parts.xslt
│ │ ├── class-summary.xslt
│ │ ├── cookies.js
│ │ ├── effectsSummary.xslt
│ │ ├── eventsGeneratedSummary.xslt
│ │ ├── fieldSummary.xslt
│ │ ├── help.js
│ │ ├── images
│ │ ├── AVMIcon12x12.png
│ │ ├── AirIcon12x12.gif
│ │ ├── P_AlternativeMetadataIndicator_30x28_N.png
│ │ ├── collapsed.gif
│ │ ├── detailHeaderRule.jpg
│ │ ├── detailSectionHeader.jpg
│ │ ├── expanded.gif
│ │ ├── inherit-arrow.gif
│ │ ├── inheritedSummary.gif
│ │ ├── logo.jpg
│ │ ├── titleTableBottom.jpg
│ │ ├── titleTableMiddle.jpg
│ │ └── titleTableTop.jpg
│ │ ├── index-list.html
│ │ ├── index.html
│ │ ├── merge_dita_xml.xslt
│ │ ├── methodSummary.xslt
│ │ ├── mxml-tags.html
│ │ ├── override.css
│ │ ├── package-detail.xslt
│ │ ├── package-frame.html
│ │ ├── package-list.xslt
│ │ ├── package-summary.xslt
│ │ ├── package.xslt
│ │ ├── prettify.css
│ │ ├── prettify.js
│ │ ├── print.css
│ │ ├── processHTML.xslt
│ │ ├── style.css
│ │ ├── stylesSummary.xslt
│ │ └── title-bar.html
└── manifest.xml
├── redbean.cfg
└── src
├── C
└── unistd
│ └── which.as
├── Library.as
├── crypto
└── generateRandomBytes.as
├── libraries
└── uanalytics
│ ├── SimplestTracker.as
│ ├── tracker
│ ├── AppTracker.as
│ ├── ApplicationInfo.as
│ ├── CliTracker.as
│ ├── CommandLineTracker.as
│ ├── DataSource.as
│ ├── DefaultTracker.as
│ ├── HitType.as
│ ├── SessionControl.as
│ ├── SystemInfo.as
│ ├── TimingInfo.as
│ ├── WebTracker.as
│ ├── addons
│ │ ├── DebugFileSystemStorage.as
│ │ ├── DebugSharedObjectStorage.as
│ │ └── Twitter.as
│ └── senders
│ │ ├── BSDSocketHitSender.as
│ │ ├── CurlHitSender.as
│ │ ├── DebugHitSender.as
│ │ ├── LoaderHitSender.as
│ │ ├── TraceHitSender.as
│ │ ├── URLLoaderHitSender.as
│ │ └── URLStreamHitSender.as
│ ├── tracking
│ ├── AnalyticsSender.as
│ ├── AnalyticsTracker.as
│ ├── Configuration.as
│ ├── HitModel.as
│ ├── HitSampler.as
│ ├── HitSender.as
│ ├── Metadata.as
│ ├── RateLimitError.as
│ ├── RateLimiter.as
│ └── Tracker.as
│ └── utils
│ ├── crc32.as
│ ├── generateAIRAppInfo.as
│ ├── generateAIRSystemInfo.as
│ ├── generateCLISystemInfo.as
│ ├── generateCLIUUID.as
│ ├── generateCLIUserAgent.as
│ ├── generateFlashSystemInfo.as
│ ├── generateUUID.as
│ ├── getAIRScreenColors.as
│ ├── getAIRUserLanguage.as
│ ├── getCLIHostname.as
│ ├── getCurrentScreen.as
│ ├── getDocumentEncoding.as
│ ├── getFlashVersion.as
│ ├── getHostname.as
│ ├── getScreenColors.as
│ ├── getScreenResolution.as
│ ├── getUserLanguage.as
│ ├── getViewportSize.as
│ ├── isAIR.as
│ └── isDigit.as
├── uanalytics.as
├── uanalytics.png
└── version.properties
/README.md:
--------------------------------------------------------------------------------
1 | as3-universal-analytics
2 | =======================
3 |
4 | Google Universal Analytics for ActionScript 3.0
5 | (**Flash** / **AIR** / **Redtamarin**).
6 |
7 | For few years people could use [gaforflash](https://code.google.com/p/gaforflash/)
8 | to [track Flash content with Google Analytics](http://analytics.blogspot.fr/2008/11/want-to-track-adobe-flash-now-you-can.html),
9 | the solution was not perfect but it did work for the general use cases.
10 |
11 | Now, with [the evolution of Google Analytics to Universal Analytics](http://analytics.blogspot.fr/2014/04/universal-analytics-out-of-beta-into.html),
12 | we can offer the Flash Platform a new library which can cover more specific and advanced use cases.
13 |
14 | Simply put, **as3-universal-analytics** is an ActionScript 3 implementation
15 | of the [Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/v1/).
16 |
17 | Please visit the [Wiki Documentation](https://github.com/zwetan/as3-universal-analytics/wiki) to get started.
18 |
19 |
20 | Mission Statement
21 | -----------------
22 |
23 | Provide a clean and complete implementation of the Measurement Protocol.
24 |
25 |
26 |
27 | Status
28 | ------
29 |
30 | First release: [uanalytics v0.8](https://github.com/zwetan/as3-universal-analytics/releases)
31 |
32 |
33 |
34 | LICENSE
35 | -------
36 |
37 | The Source Code is subject to the terms of the [Mozilla Public License](https://www.mozilla.org/en-US/MPL/), v. 2.0
38 | or [MPL2](https://www.mozilla.org/en-US/MPL/2.0/) for short; if you have doubt or questions about this licensing
39 | please consult the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/).
40 |
41 |
42 | FAQ
43 | ---
44 |
45 | **Q: Does it replace/update/upgrade gaforflash ?**
46 | A: Yes.
47 |
48 | **Q: Is it officially supported by Google ?**
49 | A: No.
50 |
51 | **Q: Is it officially supported by Adobe ?**
52 | A: No.
53 |
54 | **Q: What is the minimum requirement ?**
55 | A: Flash Player 11 and/or Adobe AIR 3 (October 4, 2011) and/or Redtamarin (October 25, 2014).
56 |
57 | **Q: Will it work with the Flash Player plugin as a SWF embedded in an HTTML page ?**
58 | A: Yes.
59 |
60 | **Q: Will it work when I test from Flash CS, Flash CC, Flash Builder, etc. ?**
61 | A: Yes.
62 |
63 | **Q: Will it work with AIR for mobile (iOS and Android) ?**
64 | A: Yes.
65 |
66 | **Q: Will it work with AIR for desktop (Windows and Mac OS X) ?**
67 | A: Yes.
68 |
69 | **Q: Does it have a JavaScript dependency and/or bridge mode ?**
70 | A: No. It is optional for advanced use.
71 |
72 | **Q: Will it work with Redtamarin server side (Linux and Mac OS X) ?**
73 | A: Yes.
74 |
75 | **Q: Will it work from a Linux (or Mac OS X) shell script ?**
76 | A: Yes.
77 |
78 | **Q: Will it work with Redtamarin under Windows ?**
79 | A: Not yet. It will work in a future update.
80 |
81 | **Q: Do you plan an ActionScript 2.0 version ?**
82 | A: No. Unlikely to ever happen.
83 |
84 |
--------------------------------------------------------------------------------
/build.as3:
--------------------------------------------------------------------------------
1 | import redbean.*;
2 | import shell.FileSystem;
3 |
4 | compile( "src/uanalytics.as" );
5 |
6 | if( FileSystem.exists( "uanalytics.abc" ) )
7 | {
8 | FileSystem.removeFile( "uanalytics.abc" );
9 | }
10 |
11 | FileSystem.move( "src/uanalytics.abc", "uanalytics.abc" );
12 |
--------------------------------------------------------------------------------
/build/build.properties:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | release.dir = bin-release
6 | deploy.dir = bin-deploy
7 | docs.dir = docs
8 |
9 | project.name = uanalytics
10 | project.fullname = as3-universal-analytics
11 | project.src = src
12 | project.lib-swc = lib-swc
13 | project.as = ${project.name}.as
14 | project.swc = ${project.name}.swc
15 | project.abc = ${project.name}.abc
16 |
17 | project.namespace = http://github.com/zwetan/as3-universal-analytics
18 | project.manifest = build/manifest.xml
19 | project.version = ${version.major}.${version.minor}.${version.build}
20 |
21 | asdoc.main.title = ${project.fullname}
22 | asdoc.window.title = ${project.fullname} v${project.version}
23 | asdoc.footer = ${project.name} v${project.version}
24 | asdoc.output = ${docs.dir}/uanalytics
25 |
--------------------------------------------------------------------------------
/build/common.properties:
--------------------------------------------------------------------------------
1 | FLEX_HOME_MAC = /sdk/flex/4_6
2 | FLEX_HOME_WIN = c:/sdk/flex/4_6
3 |
4 | local.flashplayerversion = 11
5 | local.swfversion = 13
6 |
7 | build.component = true
8 | build.noswc = false
9 | build.noabc = false
10 |
11 | build.documentation = true
12 | build.nodoc = false
13 | build.fatswc = true
14 |
15 | build.release = true
16 | build.nozip = false
--------------------------------------------------------------------------------
/build/doc/package.description.xml:
--------------------------------------------------------------------------------
1 |
51 |
52 |
55 |
61 |
65 |
81 |
128 |
82 |
127 |
119 |
123 |
A | 36 |N | 37 |
B | 40 |O | 41 |
C | 44 |P | 45 |
D | 48 |Q | 49 |
E | 52 |R | 53 |
F | 56 |S | 57 |
G | 60 |T | 61 |
H | 64 |U | 65 |
I | 68 |V | 69 |
J | 72 |W | 73 |
K | 76 |X | 77 |
L | 80 |Y | 81 |
M | 84 |Z | 85 |
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
28 |
29 | Link toNon-frame version.
30 |
29 |
|
38 | ![]() |
39 | ||||
42 |
|
54 |
15 | * The which utility takes a command name and searches the path 16 | * for each executable file that would be run had this 17 | * command actually been invoked. 18 | *
19 | * 20 | * @example Usage 21 | *true
list all instances of executables found.
28 | * @return the full path of the program or the empty string if not found.
29 | *
30 | * @langversion 3.0
31 | * @playerversion AVM 0.4
32 | * @playerversion POSIX +
33 | *
34 | * @see http://docs.redtamarin.com/latest/C/stdlib/package.html#getenv() C.stdlib.getenv()
35 | * @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/getenv.html getenv()
36 | * @see http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script Check if a program exists from a bash script
37 | * @see http://www.opensource.apple.com/source/shell_cmds/shell_cmds-170/which/which.c shell command which
38 | */
39 | public function which( name:String, all:Boolean = false ):String
40 | {
41 | var PATH:String = getenv( "PATH" );
42 | if( PATH == "" ) { return ""; }
43 |
44 | /* Note:
45 | usual paths are
46 |
47 | /opt/local/bin
48 | /opt/local/sbin
49 | /usr/local/bin
50 | /usr/bin
51 | /bin
52 | /usr/sbin
53 | /sbin
54 | */
55 | var paths:Array = PATH.split( ":" );
56 | paths.push( "." );
57 |
58 | var is_there:Function = function( candidate:String ):Boolean
59 | {
60 | var fin:* = new status();
61 | /* Note:
62 | getlogin() != "root"
63 | should be
64 | getuid() != 0
65 | */
66 | if( (access( candidate, X_OK ) == 0) &&
67 | (stat( candidate, fin ) == 0) &&
68 | S_ISREG( fin.st_mode ) &&
69 | ( (getlogin() != "root") ||
70 | ((fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) ) )
71 | {
72 | return true;
73 | }
74 |
75 | return false;
76 | }
77 |
78 | var found:String = "";
79 |
80 | var i:uint;
81 | var len:uint = paths.length;
82 | var candidate:String;
83 | for( i = 0; i < len; i++ )
84 | {
85 | candidate = paths[i] + "/" + name;
86 | if( is_there( candidate ) )
87 | {
88 | if( all )
89 | {
90 | found += (found == "" ? "": " ") + candidate;
91 | }
92 | else
93 | {
94 | return candidate;
95 | }
96 | }
97 | }
98 |
99 | return found;
100 | }
101 |
102 | }
--------------------------------------------------------------------------------
/src/Library.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package
6 | {
7 | import flash.display.Sprite;
8 |
9 | /**
10 | * The basic framework Library to be included in the SWC.
11 | *
12 | * 13 | * Note: This class is not a component, it is just 14 | * a shim that allow to declare the SWC manifest and associate an icon file. 15 | *
16 | */ 17 | [ExcludeClass] 18 | [IconFile("uanalytics.png")] 19 | public class Library extends Sprite 20 | { 21 | public function Library() 22 | { 23 | super(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/crypto/generateRandomBytes.as: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | package crypto 6 | { 7 | import flash.utils.ByteArray; 8 | 9 | import shell.Program; 10 | 11 | /** 12 | * Generates a sequence of random bytes. 13 | * 14 | *
15 | * Use generateRandomBytes()
to generate cryptographic keys,
16 | * strong identifiers, session ids, and so on.
17 | * The random sequence is generated using cryptographically strong functions
18 | * provided by the operating system.
19 | * If the appropriate function is not available on an individual client
20 | * computer or device, then an error is thrown.
21 | *
24 | * Note: this is a temporary solution as the current redtamarin runtimes
25 | * does not implment flash.crypto.generateRandomBytes
yet.
26 | * It will work under Linux and Mac OS X but not under Windows (unless under a cygwin shell).
27 | *
16 | * By default, all the parameters are empty (not initialised).
17 | * Only the non-empty (or initialised) parameters wil be exported
18 | * by the toDictionary()
function.
19 | *
12 | * Those values are examples of what we think is "common use case", 13 | * you can use any value you want. 14 | *
15 | * 16 | *17 | * In general, we think you would want to differentiate between 18 | * the web: a SWF hosted in an online HTML page, 19 | * an app: an AIR application, 20 | * and commandline: a Redtamarin command-line program. 21 | *
22 | * 23 | *24 | * You may want also to differentiate between 25 | * a desktop app: AIR published for the desktop 26 | * and a mobile app: AIR published for mobile. 27 | *
28 | * 29 | *30 | * That said, you could use any values, here few more examples: 31 | * "cms" (content management system), "server" (when you do tracking server-side), 32 | * "shellscript" (when using a shell script vs a static binary), etc. 33 | *
34 | * 35 | * @playerversion Flash 11 36 | * @playerversion AIR 3.0 37 | * @playerversion AVM 0.4 38 | * @langversion 3.0 39 | * 40 | * @see libraries.uanalytics.tracking.Tracker#DATA_SOURCE Tracker.DATA_SOURCE 41 | * @see libraries.uanalytics.tracking.Metadata Metadata 42 | */ 43 | public class DataSource 44 | { 45 | 46 | /** 47 | * When hit is sent from an online SWF. 48 | * 49 | * @playerversion Flash 11 50 | * @playerversion AIR 3.0 51 | * @playerversion AVM 0.4 52 | * @langversion 3.0 53 | */ 54 | public static const WEB:String = "web"; 55 | 56 | /** 57 | * When hit is sent from an AIR application. 58 | * 59 | * @playerversion Flash 11 60 | * @playerversion AIR 3.0 61 | * @playerversion AVM 0.4 62 | * @langversion 3.0 63 | */ 64 | public static const APP:String = "app"; 65 | 66 | /** 67 | * When hit is sent from a desktop AIR application. 68 | * 69 | * @playerversion Flash 11 70 | * @playerversion AIR 3.0 71 | * @playerversion AVM 0.4 72 | * @langversion 3.0 73 | */ 74 | public static const DESKTOP:String = "desktop"; 75 | 76 | /** 77 | * When hit is sent from a mobile AIR application. 78 | * 79 | * @playerversion Flash 11 80 | * @playerversion AIR 3.0 81 | * @playerversion AVM 0.4 82 | * @langversion 3.0 83 | */ 84 | public static const MOBILE:String = "mobile"; 85 | 86 | /** 87 | * When hit is sent from a Redtamarin command-line program. 88 | * 89 | * @playerversion Flash 11 90 | * @playerversion AIR 3.0 91 | * @playerversion AVM 0.4 92 | * @langversion 3.0 93 | */ 94 | public static const COMMAND_LINE:String = "commandline"; 95 | 96 | /** 97 | * Creates a DataSource. 98 | * 99 | * @playerversion Flash 11 100 | * @playerversion AIR 3.0 101 | * @playerversion AVM 0.4 102 | * @langversion 3.0 103 | */ 104 | public function DataSource() 105 | { 106 | super(); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /src/libraries/uanalytics/tracker/HitType.as: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | package libraries.uanalytics.tracker 6 | { 7 | import flash.system.System; 8 | import flash.utils.describeType; 9 | 10 | /** 11 | * The HitType class defines allowed values for the "hit type" parameter. 12 | * 13 | * @playerversion Flash 11 14 | * @playerversion AIR 3.0 15 | * @playerversion AVM 0.4 16 | * @langversion 3.0 17 | * 18 | * @see libraries.uanalytics.tracking.Tracker#send() Tracker.send() 19 | * @see libraries.uanalytics.tracking.Tracker#HIT_TYPE Tracker.HIT_TYPE 20 | * @see libraries.uanalytics.tracking.Metadata Metadata 21 | * @see http://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#t Hit Type 22 | */ 23 | public class HitType 24 | { 25 | 26 | /** 27 | * Defines a "pageview" hit type. 28 | * 29 | * @playerversion Flash 11 30 | * @playerversion AIR 3.0 31 | * @playerversion AVM 0.4 32 | * @langversion 3.0 33 | */ 34 | public static const PAGEVIEW:String = "pageview"; 35 | 36 | /** 37 | * Defines a "screenview" hit type. 38 | * 39 | * @playerversion Flash 11 40 | * @playerversion AIR 3.0 41 | * @playerversion AVM 0.4 42 | * @langversion 3.0 43 | */ 44 | public static const SCREENVIEW:String = "screenview"; 45 | 46 | /** 47 | * Defines an "event" hit type. 48 | * 49 | * @playerversion Flash 11 50 | * @playerversion AIR 3.0 51 | * @playerversion AVM 0.4 52 | * @langversion 3.0 53 | */ 54 | public static const EVENT:String = "event"; 55 | 56 | /** 57 | * Defines a "transaction" hit type. 58 | * 59 | * @playerversion Flash 11 60 | * @playerversion AIR 3.0 61 | * @playerversion AVM 0.4 62 | * @langversion 3.0 63 | */ 64 | public static const TRANSACTION:String = "transaction"; 65 | 66 | /** 67 | * Defines an "item" hit type. 68 | * 69 | * @playerversion Flash 11 70 | * @playerversion AIR 3.0 71 | * @playerversion AVM 0.4 72 | * @langversion 3.0 73 | */ 74 | public static const ITEM:String = "item"; 75 | 76 | /** 77 | * Defines a "social" hit type. 78 | * 79 | * @playerversion Flash 11 80 | * @playerversion AIR 3.0 81 | * @playerversion AVM 0.4 82 | * @langversion 3.0 83 | */ 84 | public static const SOCIAL:String = "social"; 85 | 86 | /** 87 | * Defines an "exception" hit type. 88 | * 89 | * @playerversion Flash 11 90 | * @playerversion AIR 3.0 91 | * @playerversion AVM 0.4 92 | * @langversion 3.0 93 | */ 94 | public static const EXCEPTION:String = "exception"; 95 | 96 | /** 97 | * Defines a "timing" hit type. 98 | * 99 | * @playerversion Flash 11 100 | * @playerversion AIR 3.0 101 | * @playerversion AVM 0.4 102 | * @langversion 3.0 103 | */ 104 | public static const TIMING:String = "timing"; 105 | 106 | /** 107 | * Returnstrue
is the passed string type
108 | * is a valid Hit Type.
109 | *
110 | * @playerversion Flash 11
111 | * @playerversion AIR 3.0
112 | * @playerversion AVM 0.4
113 | * @langversion 3.0
114 | */
115 | public static function isValid( type:String ):Boolean
116 | {
117 | var _class:XML = describeType( HitType );
118 | var found:Boolean = false;
119 |
120 | var property:String;
121 | for each( var member:XML in _class.constant )
122 | {
123 | property = String( member.@name );
124 |
125 | if( HitType[ property ] == type )
126 | {
127 | found = true;
128 | break;
129 | }
130 |
131 | }
132 | System.disposeXML( _class );
133 |
134 | if( found )
135 | {
136 | return true;
137 | }
138 |
139 | return false;
140 | }
141 |
142 | /**
143 | * Creates a HitType.
144 | *
145 | * @playerversion Flash 11
146 | * @playerversion AIR 3.0
147 | * @playerversion AVM 0.4
148 | * @langversion 3.0
149 | */
150 | public function HitType()
151 | {
152 | super();
153 | }
154 | }
155 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/tracker/SessionControl.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package libraries.uanalytics.tracker
6 | {
7 |
8 | /**
9 | * The SessionControl class defines allowed values for the
10 | * "session control" parameter.
11 | *
12 | * @playerversion Flash 11
13 | * @playerversion AIR 3.0
14 | * @playerversion AVM 0.4
15 | * @langversion 3.0
16 | *
17 | * see: libraries.uanalytics.tracking.Tracker#SESSION_CONTROL Tracker.SESSION_CONTROL
18 | * @see libraries.uanalytics.tracking.Metadata Metadata
19 | * @see http://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#sc Session Control
20 | */
21 | public class SessionControl
22 | {
23 |
24 | /**
25 | * Forces a new session to start with the hit request.
26 | *
27 | * @playerversion Flash 11
28 | * @playerversion AIR 3.0
29 | * @playerversion AVM 0.4
30 | * @langversion 3.0
31 | */
32 | public static const START:String = "start";
33 |
34 | /**
35 | * Forces the current session to end with the hit request.
36 | *
37 | * @playerversion Flash 11
38 | * @playerversion AIR 3.0
39 | * @playerversion AVM 0.4
40 | * @langversion 3.0
41 | */
42 | public static const END:String = "end";
43 |
44 | /**
45 | * Creates a SessionControl.
46 | *
47 | * @playerversion Flash 11
48 | * @playerversion AIR 3.0
49 | * @playerversion AVM 0.4
50 | * @langversion 3.0
51 | */
52 | public function SessionControl()
53 | {
54 | super();
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/tracker/SystemInfo.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package libraries.uanalytics.tracker
6 | {
7 | import flash.utils.Dictionary;
8 |
9 | import libraries.uanalytics.tracking.Tracker;
10 |
11 | /**
12 | * The SystemInfo defines parameters meant to be used
13 | * for System Information Tracking.
14 | *
15 | *
16 | * By default, all the parameters are empty (not initialised).
17 | * Only the non-empty (or initialised) parameters wil be exported
18 | * by the toDictionary()
function.
19 | *
23 | * The equivalent of analytics.js for online SWF files. 24 | *
25 | *26 | * analytics.js: 27 | * Each analytics.js tracker object starts with 20 hits that are replenished 28 | * at a rate of 2 hit per second. Applies to all hits except for ecommerce 29 | * (item or transaction). 30 | *31 | * 32 | *
33 | * Features: 34 | *
35 | *RateLimiter
settings: the tracker starts with 20 hits
38 | * that are replenished at a rate of 2 hits per second.
39 | * SharedObject
storage to save/restore the ClientId.
45 | * DefaultTracker
78 | * SharedObject
123 | * to save and/or restore the ClientId.
124 | */
125 | protected override function _getClientID():String
126 | {
127 | // Load the SharedObject '_ga'
128 | _storage = SharedObject.getLocal( _config.storageName );
129 | var cid:String;
130 |
131 | if( !_storage.data.clientid )
132 | {
133 | // CID not found, generate Client ID
134 | cid = generateUUID();
135 |
136 | // Save CID into SharedObject
137 | _storage.data.clientid = cid;
138 |
139 | var flushStatus:String = null;
140 | try
141 | {
142 | flushStatus = _storage.flush( 1024 ); //1KB
143 | }
144 | catch( e:Error )
145 | {
146 | //trace( "Could not write SharedObject to disk: " + e.message );
147 | }
148 |
149 | if( flushStatus != null )
150 | {
151 | switch( flushStatus )
152 | {
153 | case SharedObjectFlushStatus.PENDING:
154 | // Requesting permission to save object...
155 | _storage.addEventListener( NetStatusEvent.NET_STATUS, onFlushStatus );
156 | break;
157 |
158 | case SharedObjectFlushStatus.FLUSHED:
159 | // Value flushed to disk"
160 | break;
161 | }
162 | }
163 |
164 | }
165 | else
166 | {
167 | // CID found, restore from SharedObject
168 | cid = _storage.data.clientid;
169 | }
170 |
171 | return cid;
172 | }
173 |
174 | protected function onFlushStatus( event:NetStatusEvent ):void
175 | {
176 | // User closed permission dialog...
177 | _storage.removeEventListener( NetStatusEvent.NET_STATUS, onFlushStatus);
178 |
179 | switch( event.info.code )
180 | {
181 | case "SharedObject.Flush.Success":
182 | // User granted permission, value saved
183 | break;
184 |
185 | case "SharedObject.Flush.Failed":
186 | // User denied permission, value not saved
187 | break;
188 | }
189 | }
190 |
191 | }
192 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/tracker/addons/DebugFileSystemStorage.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package libraries.uanalytics.tracker.addons
6 | {
7 | import C.errno.*;
8 | import C.sys.stat.*;
9 | import C.unistd.*;
10 | import C.stdio.*;
11 |
12 | import flash.utils.ByteArray;
13 |
14 | import libraries.uanalytics.tracking.Configuration;
15 |
16 | import shell.FileSystem;
17 |
18 | /**
19 | * Utility function to debug and/or reset the File System storage.
20 | *
21 | * @param show show informations and datas of the sotrage (default to true
).
22 | * @param reset clear the storage from its data (default to false
).
23 | *
24 | * @playerversion AVM 0.4
25 | * @langversion 3.0
26 | */
27 | public function DebugFileSystemStorage( show:Boolean = true,
28 | reset:Boolean = false ):void
29 | {
30 | var homedir:String = FileSystem.homeDirectory;
31 |
32 | if( homedir == "" )
33 | {
34 | homedir = "/"; // root dir
35 | }
36 |
37 | var exists:int = access( homedir, F_OK );
38 | if( exists < 0 )
39 | {
40 | throw new CError( errno );
41 | }
42 |
43 | var canread:int = access( homedir, R_OK );
44 | if( canread < 0 )
45 | {
46 | throw new CError( errno );
47 | }
48 |
49 | var canwrite:int = access( homedir, W_OK );
50 | if( canwrite < 0 )
51 | {
52 | throw new CError( errno );
53 | }
54 |
55 | // by that point we are sure the HOME directory exists and is readable/writable
56 | // for ex: /home/username
57 |
58 | var savepath:String = homedir + "/.uanalytics";
59 | var s_exists:int = access( savepath, F_OK );
60 | if( s_exists < 0 )
61 | {
62 | throw new CError( errno );
63 | }
64 |
65 | // by that point we are sure our preference dir .uanalytics exists
66 | // for ex: /home/username/.uanalytics
67 |
68 | var config:Configuration = new Configuration();
69 | var filepath:String = savepath + "/" + config.storageName;
70 | var data:String = "";
71 |
72 | var f_exists:int = access( filepath, F_OK );
73 | if( f_exists < 0 )
74 | {
75 | throw new CError( errno );
76 | }
77 | else
78 | {
79 | // the save file already exists
80 | data = FileSystem.read( filepath );
81 | }
82 |
83 | if( show )
84 | {
85 | trace( "File: " + filepath );
86 | trace( "size: " + data.length + " bytes" );
87 | trace( "data:" );
88 | trace( " |_ " + data );
89 | }
90 |
91 | if( reset )
92 | {
93 | // bug: does not allow you to write an empty file
94 | //FileSystem.write( filepath, "" );
95 | var fp:FILE = fopen( filepath, "w" );
96 | if( fp )
97 | {
98 | var bytes:ByteArray = new ByteArray();
99 | fwrite( bytes, bytes.length, fp );
100 | fflush( fp );
101 | bytes.clear();
102 | fclose( fp );
103 | }
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/tracker/addons/DebugSharedObjectStorage.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package libraries.uanalytics.tracker.addons
6 | {
7 | import flash.net.SharedObject;
8 |
9 | import libraries.uanalytics.tracking.Configuration;
10 |
11 | /**
12 | * Utility function to debug and/or reset the SharedObject
13 | * storage.
14 | *
15 | * @param show show informations and datas of the sotrage (default to true
).
16 | * @param reset clear the storage from its data (default to false
).
17 | *
18 | * @playerversion Flash 11
19 | * @playerversion AIR 3.0
20 | * @langversion 3.0
21 | */
22 | public function DebugSharedObjectStorage( show:Boolean = true,
23 | reset:Boolean = false ):void
24 | {
25 | var conf:Configuration = new Configuration();
26 | var so:SharedObject = SharedObject.getLocal( conf.storageName );
27 |
28 | if( show )
29 | {
30 | trace( "SharedObject: " + conf.storageName );
31 | trace( "size: " + so.size + " bytes" );
32 | trace( "data:" );
33 | for( var m:String in so.data )
34 | {
35 | trace( " |_ " + m + ": " + so.data[m] );
36 | }
37 | }
38 |
39 | if( reset )
40 | {
41 | so.clear();
42 | }
43 |
44 | }
45 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/tracker/addons/Twitter.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package libraries.uanalytics.tracker.addons
6 | {
7 | import libraries.uanalytics.tracking.AnalyticsTracker;
8 |
9 | /**
10 | * Helper class to send Twitter social hits.
11 | *
12 | * 13 | * To integrate with a Twitter API. 14 | *
15 | * 16 | * @example Usage 17 | *122 | * Some example of buttons: Tweet, Follow, hashtag, Mention, etc. 123 | *
124 | * 125 | * @param target the target of the social interaction. 126 | * @return false if the social hit has not been sent due to sampling 127 | * or other reasons. 128 | * 129 | * @playerversion Flash 11 130 | * @playerversion AIR 3.0 131 | * @playerversion AVM 0.4 132 | * @langversion 3.0 133 | */ 134 | public function click( target:String ):Boolean 135 | { 136 | return _tracker.social( NETWORK, CLICK, target ); 137 | } 138 | 139 | /** 140 | * The action of publishing a tweet. 141 | * 142 | * @param target the target of the social interaction. 143 | * @return false if the social hit has not been sent due to sampling 144 | * or other reasons. 145 | * 146 | * @playerversion Flash 11 147 | * @playerversion AIR 3.0 148 | * @playerversion AVM 0.4 149 | * @langversion 3.0 150 | */ 151 | public function tweet( target:String ):Boolean 152 | { 153 | return _tracker.social( NETWORK, TWEET, target ); 154 | } 155 | 156 | /** 157 | * The action to retweet a tweet. 158 | * 159 | * @param target the target of the social interaction. 160 | * @return false if the social hit has not been sent due to sampling 161 | * or other reasons. 162 | * 163 | * @playerversion Flash 11 164 | * @playerversion AIR 3.0 165 | * @playerversion AVM 0.4 166 | * @langversion 3.0 167 | */ 168 | public function retweet( target:String ):Boolean 169 | { 170 | return _tracker.social( NETWORK, RETWEET, target ); 171 | } 172 | 173 | /** 174 | * The action to favorite a tweet. 175 | * 176 | * @param target the target of the social interaction. 177 | * @return false if the social hit has not been sent due to sampling 178 | * or other reasons. 179 | * 180 | * @playerversion Flash 11 181 | * @playerversion AIR 3.0 182 | * @playerversion AVM 0.4 183 | * @langversion 3.0 184 | */ 185 | public function star( target:String ):Boolean 186 | { 187 | return _tracker.social( NETWORK, STAR, target ); 188 | } 189 | 190 | /** 191 | * The action to follow a twitter user. 192 | * 193 | * @param target the target of the social interaction. 194 | * @return false if the social hit has not been sent due to sampling 195 | * or other reasons. 196 | * 197 | * @playerversion Flash 11 198 | * @playerversion AIR 3.0 199 | * @playerversion AVM 0.4 200 | * @langversion 3.0 201 | */ 202 | public function follow( target:String ):Boolean 203 | { 204 | return _tracker.social( NETWORK, FOLLOW, target ); 205 | } 206 | 207 | } 208 | } -------------------------------------------------------------------------------- /src/libraries/uanalytics/tracker/senders/CurlHitSender.as: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | package libraries.uanalytics.tracker.senders 6 | { 7 | import libraries.uanalytics.tracking.AnalyticsTracker; 8 | import libraries.uanalytics.tracking.Configuration; 9 | import libraries.uanalytics.tracking.HitModel; 10 | import libraries.uanalytics.tracking.HitSender; 11 | 12 | import shell.Program; 13 | import C.unistd.which; 14 | 15 | /** 16 | * AHitSender
based on the cURL command-line tool.
17 | *
18 | *
19 | * As Redtamarin doesn't have SSL support for sockets on the command-line
20 | * cURL allow to fill this void.
21 | * Mainly to be able to test with the Measurement Protocol Validation Server
22 | * which works only with HTTPS, and/or if you absolutely have to use HTTPS.
23 | *
DebugHitSender
will send hit requests
24 | * to the Measurement Protocol Validation Server.
25 | *
26 | * 27 | * To ensure that your hits are correctly formatted and contain all required 28 | * parameters, you can test them against the validation server before 29 | * deploying them to production. 30 | *
31 | * 32 | *
33 | * The sender use the endpoint /debug/collect
34 | * instead of /collect
.
35 | * Hits sent to the Measurement Protocol Validation Server will not show up
36 | * in reports. They are for debugging only.
37 | *
HitSender
that will trace the hit requests to the console
14 | * output.
15 | *
16 | * 17 | * It will work only in a debug Flash Player, debug AIR application, 18 | * and with the debug redshell (or as3shebang). 19 | * It will not send any data to the Google Analytics servers. 20 | *
21 | * 22 | * @example Usage 23 | *12 | * The strict minimum of what a sender need to implement 13 | * is to send a data model to a URL. 14 | *
15 | * 16 | *
17 | * For a Flash / AIR implementation see URLLoaderHitSender
,
18 | * for a Redtamarin implementation see BSDSocketHitSender
.
19 | *
13 | * Users primarily get and set field values. 14 | *
15 | * 16 | * @playerversion Flash 11 17 | * @playerversion AIR 3.0 18 | * @playerversion AVM 0.4 19 | * @langversion 3.0 20 | */ 21 | public class HitModel 22 | { 23 | private var _data:Dictionary; 24 | private var _metadata:Metadata; 25 | 26 | /** 27 | * Create a new HitModel. 28 | * 29 | * @playerversion Flash 11 30 | * @playerversion AIR 3.0 31 | * @playerversion AVM 0.4 32 | * @langversion 3.0 33 | */ 34 | public function HitModel() 35 | { 36 | _metadata = new Metadata(); 37 | clear(); 38 | } 39 | 40 | /** 41 | * Set a model field to a specific value. 42 | * 43 | *
44 | * Common field names are provided as static members of the Tracker
class.
45 | * You may also use your own field names to store information in the data
46 | * model but they will not be sent in the tracking beacon.
47 | *
66 | * See the set
method for a description of possible field
67 | * names.
68 | *
HitModel
to this model.
86 | *
87 | * @param model the model to add.
88 | *
89 | * @playerversion Flash 11
90 | * @playerversion AIR 3.0
91 | * @playerversion AVM 0.4
92 | * @langversion 3.0
93 | */
94 | public function add( model:HitModel ):void
95 | {
96 | for( var key:String in model._data )
97 | {
98 | _data[ key ] = model._data[ key ];
99 | }
100 | }
101 |
102 | /**
103 | * Returns a new copy of this HitModel
with all the same
104 | * fields set.
105 | *
106 | * @playerversion Flash 11
107 | * @playerversion AIR 3.0
108 | * @playerversion AVM 0.4
109 | * @langversion 3.0
110 | */
111 | public function clone():HitModel
112 | {
113 | var copy:HitModel = new HitModel();
114 |
115 | for( var key:String in _data )
116 | {
117 | copy._data[ key ] = _data[ key ];
118 | }
119 |
120 | return copy;
121 | }
122 |
123 | /**
124 | * Clear all the fields set in the model.
125 | *
126 | * @playerversion Flash 11
127 | * @playerversion AIR 3.0
128 | * @playerversion AVM 0.4
129 | * @langversion 3.0
130 | */
131 | public function clear():void
132 | {
133 | _data = new Dictionary();
134 | }
135 |
136 | /**
137 | * Returns all of the field names currently set in the model.
138 | *
139 | * @playerversion Flash 11
140 | * @playerversion AIR 3.0
141 | * @playerversion AVM 0.4
142 | * @langversion 3.0
143 | */
144 | public function getFieldNames():Vector.
17 | * Sampling is determined on a per-client basis as identified by
18 | * the Tracker.CLIENT_ID
field.
19 | * This means that either all or none of the hits from a particular client
20 | * will be sent.
21 | *
24 | * By default we use the value set in Configuration
,
25 | * you can edit the configuration to use something else than the
26 | * default (100%).
27 | *
parseFloat()
63 | * except that trailing non-numeric characters are not ignored and return NaN.
64 | *
65 | * @param The string to read and convert to a Number.
66 | * @return A number or NaN (not a number).
67 | *
68 | * @playerversion Flash 11
69 | * @playerversion AIR 3.0
70 | * @playerversion AVM 0.4
71 | * @langversion 3.0
72 | */
73 | private static function _parseNumber( str:String ):Number
74 | {
75 | if( str == "" ) { return NaN; }
76 |
77 | var i:uint;
78 | var l:uint = str.length;
79 | var dot:uint = 0;
80 | for( i=0; iSAMPLE_RATE
field.
97 | *
98 | *
99 | * @param model
100 | *
101 | * @return true if the hit should be sampled out and not sent.
102 | *
103 | * @playerversion Flash 11
104 | * @playerversion AIR 3.0
105 | * @playerversion AVM 0.4
106 | * @langversion 3.0
107 | */
108 | public static function isSampled( model:HitModel, samplerate:String = "" ):Boolean
109 | {
110 | var sampleRate:Number = getSampleRate( samplerate );
111 |
112 | return (sampleRate < 100) && (_hashString( model.get(Tracker.CLIENT_ID) ) % 10000 >= 100 * sampleRate)
113 | }
114 |
115 | /**
116 | * Parse the specified sample rate string expressed as a floating point numbers.
117 | *
118 | *
119 | * Values will be rounded to the nearest 100th.
120 | * Invalid numbers will return 0
.
121 | * Values greater than 100 will return 100
.
122 | *
12 | * To be considered as an abstract class to extend from. 13 | *
14 | * 15 | * @example Usage 16 | * 17 | *70 | * Do not use or instanciate this class directly, extend it instead. 71 | *
72 | * 73 | * @playerversion Flash 11 74 | * @playerversion AIR 3.0 75 | * @playerversion AVM 0.4 76 | * @langversion 3.0 77 | */ 78 | public function HitSender() 79 | { 80 | super(); 81 | } 82 | 83 | /** 84 | * Adds the named query parameter and value to the specified String. 85 | * This take care of URL encoding special characters. 86 | * 87 | * @param name the HitModel key name. 88 | * @param value the field value. 89 | * 90 | * @return a string formated such as&NAME=VALUE
91 | *
92 | * @playerversion Flash 11
93 | * @playerversion AIR 3.0
94 | * @playerversion AVM 0.4
95 | * @langversion 3.0
96 | */
97 | protected function _addParameter( name:String, value:String ):String
98 | {
99 | var str:String = "";
100 | str += "&";
101 | str += _appendEncoded( name.substring(1) );
102 | str += "=";
103 | str += _appendEncoded( value );
104 |
105 | return str;
106 | }
107 |
108 | /**
109 | * URL encodes the specified value.
110 | *
111 | * @param value the value to encode.
112 | *
113 | * @return the value URL encoded.
114 | *
115 | * @playerversion Flash 11
116 | * @playerversion AIR 3.0
117 | * @playerversion AVM 0.4
118 | * @langversion 3.0
119 | */
120 | protected function _appendEncoded( value:String ):String
121 | {
122 | return encodeURIComponent( value );
123 | }
124 |
125 | /**
126 | * Build the hit payload from the hit model. The payload can be sent
127 | * via either setting this as the body of an HTTP POST request or
128 | * as the query parameter string of the request.
129 | *
130 | * @param model the HitModel to send.
131 | *
132 | * @return the payload representation that is used to send the hit.
133 | *
134 | * @playerversion Flash 11
135 | * @playerversion AIR 3.0
136 | * @playerversion AVM 0.4
137 | * @langversion 3.0
138 | */
139 | protected function _buildHit( model:HitModel ):String
140 | {
141 | var str:String = "";
142 |
143 | // This library supports version 1 of the tracking API.
144 | str += "v=1";
145 |
146 | if( Configuration.SDKversion != "" )
147 | {
148 | // Identify the client library version.
149 | str += _addParameter( "&_v", Configuration.SDKversion );
150 | }
151 |
152 | var names:Vector.14 | * The mecanism is based on the token bucket algorithm, 15 | * and allows you to send bursts of hits to Google Analytics, 16 | * while preventing clients from sending data too quickly. 17 | *
18 | * 19 | *
20 | * Each tracker has a maximum limit for the number of requests it can send concurrently.
21 | * The tracker also maintain a count of the number of concurrent hits that have been sent.
22 | * As a hit is sent to Google Analytics, the count decreases by one.
23 | * When the count is 0
, the maximum limit has been reached,
24 | * and no new requests are sent.
25 | * Then over a small period of time, the count is increased back to its original limit,
26 | * allowing data to be sent again.
27 | *
30 | * The limiting rate is specified in each individual trackers.
31 | * For the WebTracker
, we follow what is done with analytics.js,
32 | * the tracker starts with 20
hits that are replenished at a rate of 2
hits per second.
33 | * For the ApplicationTracker
, we follow what is done with the Android SDK and the iOS SDK,
34 | * each trackers starts with 60
hits that are replenished at a rate of 1
hit every 2 seconds.
35 | *
RateLimiter
with the specified maximum token capacity
54 | * and a specified number of new tokens generated per second (rate
).
55 | *
56 | * 57 | * The token count is initialized to the maximum token capacity. 58 | *
59 | * 60 | * @param capacity maximum number of accumulated tokens. 61 | * @param rate the number of additional tokens to regenerate per second. 62 | * @param span the time span to generate tokens (default to 1 second) 63 | * 64 | * @playerversion Flash 11 65 | * @playerversion AIR 3.0 66 | * @playerversion AVM 0.4 67 | * @langversion 3.0 68 | */ 69 | public function RateLimiter( capacity:int, rate:int, span:Number = 1 ) 70 | { 71 | _capacity = capacity; 72 | _rate = rate; 73 | _span = span; 74 | _tokenCount = capacity; 75 | _lastTime = now(); 76 | } 77 | 78 | /** 79 | * Returns the number of milliseconds that have elapsed since the 80 | * Flash runtime virtual machine for ActionScript 3.0 (AVM2) started. 81 | * 82 | *83 | * Used internally for generating tokens and useful for testing purposes. 84 | *
85 | * 86 | * @return a relative time in milliseconds. 87 | * 88 | * @playerversion Flash 11 89 | * @playerversion AIR 3.0 90 | * @playerversion AVM 0.4 91 | * @langversion 3.0 92 | */ 93 | protected function now():int 94 | { 95 | return getTimer(); 96 | } 97 | 98 | /** 99 | * Attempt to consume a token and returntrue
if successful.
100 | *
101 | * 102 | * A return value of false indicates that tokens are being consumed in excess 103 | * of the defined limits. 104 | *
105 | * 106 | * @return true if the rate limit has not been exceeded. 107 | * 108 | * @playerversion Flash 11 109 | * @playerversion AIR 3.0 110 | * @playerversion AVM 0.4 111 | * @langversion 3.0 112 | */ 113 | public function consumeToken():Boolean 114 | { 115 | var now:int = now(); 116 | var newTokens:int = Math.max( 0, (now - _lastTime) * ( (_rate * _span) / 1000) ); 117 | _tokenCount = Math.min( _tokenCount + newTokens, _capacity ); 118 | 119 | if( _tokenCount > 0 ) 120 | { 121 | _tokenCount--; 122 | _lastTime = now; 123 | return true; 124 | } 125 | 126 | return false; 127 | } 128 | 129 | } 130 | 131 | } -------------------------------------------------------------------------------- /src/libraries/uanalytics/utils/crc32.as: -------------------------------------------------------------------------------- 1 | package libraries.uanalytics.utils 2 | { 3 | import flash.utils.ByteArray; 4 | import flash.utils.Endian; 5 | 6 | /** 7 | * A class to compute the CRC-32 checksum of a data stream. 8 | * 9 | *10 | * Other names: CRC-32/ADCCP, PKZIP 11 | *
12 | * 13 | * @playerversion Flash 11 14 | * @playerversion AIR 3.0 15 | * @playerversion AVM 0.4 16 | * @langversion 3.0 17 | * 18 | * @see https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks Computation of cyclic redundancy checks 19 | */ 20 | public final class crc32 21 | { 22 | 23 | private static var lookup:Vector.
83 | * Either Endian.BIG_ENDIAN
for "Most significant bit first"
84 | * or Endian.LITTLE_ENDIAN
for "Least significant bit first".
85 | *
ApplicationInfo
10 | * from the AIR application descriptor.
11 | *
12 | * @param installerID provide a string for the installer id (optional).
13 | * @param useVersionLabel option flag to use the version label
14 | * over the version number (default to true
).
15 | *
16 | * @playerversion AIR 3.0
17 | * @langversion 3.0
18 | *
19 | * @see http://help.adobe.com/en_US/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html AIR application descriptor files
20 | * @see http://help.adobe.com/en_US/air/build/WSD079A3A2-1B38-4543-A792-06594E4325FE.html Localizing the application name and description in the AIR application installer
21 | * @see http://blog.dannypatterson.com/2010/03/namespaces-on-attributes-with-e4x-in-actionscript-3/ Namespaces on Attributes with E4X in ActionScript 3
22 | */
23 | public function generateAIRAppInfo( installerID:String = "",
24 | useVersionLabel:Boolean = true ):ApplicationInfo
25 | {
26 | var appinfo:ApplicationInfo = new ApplicationInfo();
27 |
28 | var na:NativeApplication = NativeApplication.nativeApplication;
29 | var app_name:String = "";
30 | var app_id:String = "";
31 | var app_version:String = "";
32 |
33 | if( na )
34 | {
35 | var descriptor:XML = na.applicationDescriptor;
36 |
37 | // we get the default namespace, eg. SystemInfo
9 | * from an AIR application.
10 | *
11 | *
12 | * Almost the same function as generateFlashSystemInfo()
13 | * but provide a bit more details for "screenColors" and "userLanguage".
14 | *
DisplayObject
reference (optional).
17 | *
18 | * @playerversion AIR 3.0
19 | * @langversion 3.0
20 | */
21 | public function generateAIRSystemInfo( display:DisplayObject = null ):SystemInfo
22 | {
23 | var sysinfo:SystemInfo = new SystemInfo();
24 | sysinfo.screenResolution = getScreenResolution();
25 |
26 | if( display && display.stage )
27 | {
28 | sysinfo.viewportSize = getViewportSize( display.stage );
29 | }
30 |
31 | sysinfo.documentEncoding = getDocumentEncoding();
32 |
33 | var screenColors:String = "";
34 |
35 | if( display && display.stage )
36 | {
37 | screenColors = getAIRScreenColors( display.stage );
38 | }
39 |
40 | if( screenColors == "" )
41 | {
42 | screenColors = getScreenColors();
43 | }
44 |
45 | var userLanguage:String = "";
46 |
47 | userLanguage = getAIRUserLanguage();
48 |
49 | if( userLanguage == "" )
50 | {
51 | userLanguage = getUserLanguage();
52 | }
53 |
54 | sysinfo.screenColors = screenColors;
55 | sysinfo.userLanguage = userLanguage;
56 | sysinfo.javaEnabled = false;
57 | sysinfo.flashVersion = getFlashVersion();
58 |
59 | return sysinfo;
60 | }
61 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/generateCLISystemInfo.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import shell.Runtime;
4 |
5 | import C.stdlib.*;
6 | import C.unistd.which;
7 |
8 | import libraries.uanalytics.tracker.SystemInfo;
9 |
10 | /**
11 | * Utility function to gather automatically the SystemInfo
12 | * from a command-line program.
13 | *
14 | * @playerversion AVM 0.4
15 | * @langversion 3.0
16 | *
17 | * @see http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap07.html POSIX Locale
18 | * @see http://docs.redtamarin.com/latest/shell/Runtime.html#api Runtime.api
19 | */
20 | public function generateCLISystemInfo():SystemInfo
21 | {
22 | var sysinfo:SystemInfo = new SystemInfo();
23 |
24 | /* Note:
25 | for the command-line we ignore
26 | screenResolution and viewportSize.
27 | */
28 |
29 | var documentEncoding:String = "";
30 | var userLanguage:String = "";
31 |
32 | /* Note:
33 | under POSIX, you could find somethign like
34 | LANG = en_GB.UTF-8
35 | which allow us to find out the language and encoding used
36 | */
37 | var LANG:String = getenv( "LANG" );
38 | if( LANG != "" )
39 | {
40 | var pos:int = LANG.indexOf( "." );
41 | if( pos > -1 )
42 | {
43 | userLanguage = LANG.substring( 0, pos );
44 | documentEncoding = LANG.substr( pos + 1 );
45 | }
46 | else
47 | {
48 | userLanguage = LANG;
49 | }
50 |
51 | userLanguage = userLanguage.split( "_" ).join( "-" );
52 | userLanguage = userLanguage.toLowerCase();
53 | }
54 |
55 | var JAVA:String = which( "java" );
56 |
57 | if( documentEncoding != "" )
58 | {
59 | sysinfo.documentEncoding = documentEncoding;
60 | }
61 |
62 | // as default we set for a "gray" color depth
63 | sysinfo.screenColors = "2-bits";
64 |
65 | if( userLanguage != "" )
66 | {
67 | sysinfo.userLanguage = userLanguage;
68 | }
69 |
70 | if( JAVA != "" )
71 | {
72 | sysinfo.javaEnabled = true;
73 | }
74 |
75 | var FLASH:String = "";
76 | switch( Runtime.api )
77 | {
78 |
79 | case "FP_10_0":
80 | case "AIR_1_5":
81 | FLASH = "10 0";
82 | break;
83 |
84 | case "FP_10_0_32":
85 | case "AIR_1_5_1":
86 | FLASH = "10 0 r32";
87 | break;
88 |
89 | case "FP_10_1":
90 | case "AIR_1_5_2":
91 | FLASH = "10 1";
92 | break;
93 |
94 | case "AIR_2_0":
95 | case "AIR_2_5":
96 | FLASH = "10 2";
97 | break;
98 |
99 | case "FP_10_2":
100 | case "AIR_2_6":
101 | FLASH = "10 2";
102 | break;
103 |
104 | case "SWF_12":
105 | case "AIR_2_7":
106 | FLASH = "10 3";
107 | break;
108 |
109 | case "SWF_13":
110 | case "AIR_3_0":
111 | FLASH = "11 0";
112 | break;
113 |
114 | case "SWF_14":
115 | case "AIR_3_1":
116 | FLASH = "11 1";
117 | break;
118 |
119 | case "SWF_15":
120 | case "AIR_3_2":
121 | FLASH = "11 2";
122 | break;
123 |
124 | case "SWF_16":
125 | case "AIR_3_3":
126 | FLASH = "11 3";
127 | break;
128 |
129 | case "SWF_17":
130 | case "AIR_3_4":
131 | FLASH = "11 4";
132 | break;
133 |
134 | case "SWF_18":
135 | case "AIR_3_5":
136 | FLASH = "11 5";
137 | break;
138 |
139 | case "SWF_19":
140 | case "AIR_3_6":
141 | FLASH = "11 6";
142 | break;
143 |
144 | case "FP_9_0":
145 | case "AIR_1_0":
146 | default:
147 | FLASH = "9 0";
148 | }
149 |
150 | if( FLASH != "" )
151 | {
152 | sysinfo.flashVersion = FLASH;
153 | }
154 |
155 | return sysinfo;
156 | }
157 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/generateCLIUUID.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import flash.utils.ByteArray;
4 | import crypto.generateRandomBytes;
5 |
6 | /**
7 | * Generates a version 4 UUID string representation.
8 | *
9 | *
10 | * format is xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
11 | * where x
is any hexadecimal digit
12 | * and y
is oen of 8
, 9
, A
, or B
.
13 | *
16 | * Note: this is a temporary solution as the current redtamarin runtimes
17 | * does not implment flash.crypto.generateRandomBytes
yet.
18 | * It will work under Linux and Mac OS X but not under Windows.
19 | *
24 | * In your analytics reports you will find: 25 | *
26 | *
46 | * Note:
47 | * The documentation do warn about that
48 | *
54 | * a wrong user-agent could be the reason of a hit request not being 55 | * registered by the Google Analytics Servers. 56 | *
57 | * 58 | * @param platform override the platform with either 59 | * "windows", "macintosh", "linux" 60 | * 61 | * @playerversion AVM 0.4 62 | * @langversion 3.0 63 | * 64 | * @see https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#ua User Agent Override 65 | */ 66 | public function generateCLIUserAgent( platform:String = "" ):String 67 | { 68 | var ua:String = ""; 69 | ua += "uanalytics/0.8"; 70 | ua += " "; 71 | ua += "("; 72 | 73 | if( platform == "" ) 74 | { 75 | platform = Runtime.platform; 76 | } 77 | else 78 | { 79 | switch( platform ) 80 | { 81 | case "windows": 82 | case "macintosh": 83 | case "linux": 84 | //those are valid do nothing 85 | break; 86 | 87 | default: 88 | //not valid so we use system default 89 | platform = Runtime.platform; 90 | } 91 | } 92 | 93 | 94 | var p:String = platform.substr( 0, 1 ); 95 | p = p.toUpperCase(); 96 | platform = p + platform.substring( 1 ); 97 | 98 | /* Note: 99 | the current release of Redtamarin do not detect further 100 | than the operating system platform 101 | eg. "windows", "macintosh", or "linux" 102 | 103 | It will be updated in the futur to detect the exact 104 | operating system informations. 105 | 106 | As a workaround it can also be done manually 107 | by parsing the result of 108 | lsb_release -a 109 | cat /etc/*release 110 | uname -a 111 | cat /System/Library/CoreServices/SystemVersion.plist 112 | sysctl kern.osrelease 113 | sysctl kern.osversion 114 | */ 115 | switch( platform ) 116 | { 117 | case "Windows": 118 | /* Note: 119 | "Windows" alone will not work 120 | "Windows NT" without a version will not work 121 | "Windows NT x.y" will work 122 | */ 123 | ua += platform; 124 | ua += " NT 6.1"; 125 | break; 126 | 127 | case "Macintosh": 128 | /* Note: 129 | "Macintosh" alone will not work 130 | "Macintosh; Intel Mac OS X" without a version will not work 131 | "Macintosh; Intel Mac OS X x_y" will work 132 | */ 133 | ua += platform; 134 | ua += "; Intel Mac OS X 10_10"; 135 | break; 136 | 137 | case "Linux": 138 | ua += platform; 139 | 140 | /* Note: 141 | "Linux" alone will not work 142 | either "Linux x86_64" or "Linux i686" will work 143 | */ 144 | if( Runtime.is64bit() ) 145 | { 146 | ua += " x86_64"; 147 | } 148 | else 149 | { 150 | ua += " i686"; 151 | } 152 | break; 153 | } 154 | 155 | ua += ")"; 156 | ua += " "; 157 | ua += "redtamarin/" + Runtime.redtamarin; 158 | ua += " "; 159 | ua += "AVM+/" + Runtime.version; 160 | 161 | return ua; 162 | } 163 | } -------------------------------------------------------------------------------- /src/libraries/uanalytics/utils/generateFlashSystemInfo.as: -------------------------------------------------------------------------------- 1 | package libraries.uanalytics.utils 2 | { 3 | import flash.display.DisplayObject; 4 | 5 | import libraries.uanalytics.tracker.SystemInfo; 6 | 7 | /** 8 | * Utility function to gather automatically theSystemInfo
9 | * from a SWF file.
10 | *
11 | *
12 | * Even if the display
argument is optional,
13 | * it is the only way to obtain a reference to the stage
property
14 | * to obtain the "viewport size".
15 | *
17 | * If a display object is not added to the display list, 18 | * its stage property is set to null. 19 | *20 | * 21 | * @param display
DisplayObject
reference (optional).
22 | *
23 | * @playerversion Flash 11
24 | * @playerversion AIR 3.0
25 | * @langversion 3.0
26 | *
27 | * @see http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html Basics of display programming
28 | * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#stage DisplayObject.stage property
29 | *
30 | */
31 | public function generateFlashSystemInfo( display:DisplayObject = null ):SystemInfo
32 | {
33 | /* Note:
34 | the principle is pretty simple, we build a defautl value object
35 | if we can detect system info we then fill the info
36 | otherwise we keep the value empty (or false, whatever the default).
37 |
38 | Yes we took a very conservative and safe approach to avoid as much
39 | as possible errors, ex: "I don't understand why my display object
40 | does not work", that said you can do more advanced things
41 | like: use a JS bridge to detect if Java is enabled, find out the
42 | document encoding, etc.
43 |
44 | The point is the default will work no matter what, more advanced users
45 | will know how to setup things in order to gather more info.
46 |
47 | usage:
48 | var tracker:DefaultTracker = new DefaultTracker( trackingId );
49 | var sysinfo:SystemInfo = generateFlashSystemInfo();
50 | tracker.add( sysinfo );
51 |
52 | */
53 | var sysinfo:SystemInfo = new SystemInfo();
54 | sysinfo.screenResolution = getScreenResolution();
55 |
56 | if( display && display.stage )
57 | {
58 | sysinfo.viewportSize = getViewportSize( display.stage );
59 | }
60 |
61 | sysinfo.documentEncoding = getDocumentEncoding();
62 | sysinfo.screenColors = getScreenColors();
63 | sysinfo.userLanguage = getUserLanguage();
64 | sysinfo.javaEnabled = false;
65 | sysinfo.flashVersion = getFlashVersion();
66 |
67 | return sysinfo;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/generateUUID.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import flash.crypto.generateRandomBytes;
4 | import flash.utils.ByteArray;
5 |
6 | /**
7 | * Generates a version 4 UUID string representation.
8 | *
9 | *
10 | * format is xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
11 | * where x
is any hexadecimal digit
12 | * and y
is oen of 8
, 9
, A
, or B
.
13 | *
DisplayObject
.
10 | *
11 | * @playerversion AIR 3.0
12 | * @langversion 3.0
13 | *
14 | * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Screen.html#colorDepth Screen.colorDepth
15 | */
16 | public function getAIRScreenColors( stage:Stage ):String
17 | {
18 | var current:Screen = getCurrentScreen( stage );
19 |
20 | if( current )
21 | {
22 | return current.colorDepth + "-bits";
23 | }
24 |
25 | return "";
26 | }
27 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/getAIRUserLanguage.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import flash.system.Capabilities;
4 |
5 | /**
6 | * Returns a language tag (and script and region information, where applicable)
7 | * defined by RFC4646.
8 | *
9 | *
10 | * Note:
11 | * The value of Capabilities.language
property is limited to the possible
12 | * values on this list.
13 | * Because of this limitation, Adobe AIR applications should use the first
14 | * element in the Capabilities.languages
array to determine the primary user
15 | * interface language for the system.
16 | *
Screen
8 | * of an AIR application.
9 | *
10 | * 11 | * For example, if an AIR desktop application run on a system with 12 | * multiple screens, this function will return the screen reference 13 | * under which the app is running. 14 | *
15 | * 16 | * @param stage the stage property of aDisplayObject
.
17 | *
18 | * @playerversion AIR 3.0
19 | * @langversion 3.0
20 | */
21 | public function getCurrentScreen( stage:Stage ):Screen
22 | {
23 | if( stage && stage.nativeWindow )
24 | {
25 | var screens:Array = Screen.getScreensForRectangle( stage.nativeWindow.bounds );
26 | if( screens.length > 0 )
27 | {
28 | return screens[0];
29 | }
30 | }
31 |
32 | return Screen.mainScreen;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/getDocumentEncoding.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import flash.system.System;
4 |
5 | /**
6 | * Return the encoding or code page of the current SWF file
7 | * or AIR application.
8 | *
9 | *
10 | * Because System.useCodePage = false
by default,
11 | * it should always be "UTF-8" (eg. we don't use the sytem code page
12 | * so we know we use Unicode).
13 | * And in the case where System.useCodePage = true
14 | * then it will return the empty string (eg. the system code page is used
15 | * so we don't know).
16 | *
9 | * The language is specified as a lowercase two-letter language code 10 | * from ISO 639-1. 11 | *
12 | * 13 | *14 | * On English systems, this property returns only the language code (en), 15 | * not the country code. 16 | * On Microsoft Windows systems, this property returns the user interface (UI) 17 | * language, which refers to the language used for all menus, dialog boxes, 18 | * error messages, and help files. 19 | *
20 | * 21 | * @playerversion Flash 11 22 | * @playerversion AIR 3.0 23 | * @langversion 3.0 24 | * 25 | * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Capabilities.html#language Capabilities.language 26 | * @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes List of ISO 639-1 codes 27 | */ 28 | public function getUserLanguage():String 29 | { 30 | var lang:String = Capabilities.language; 31 | 32 | // Other/unknown 33 | if( lang == "xu" ) 34 | { 35 | lang = ""; 36 | } 37 | 38 | return lang; 39 | } 40 | } -------------------------------------------------------------------------------- /src/libraries/uanalytics/utils/getViewportSize.as: -------------------------------------------------------------------------------- 1 | package libraries.uanalytics.utils 2 | { 3 | import flash.display.Stage; 4 | 5 | /** 6 | * Utility function to return the "viewport size" 7 | * (eg. the actual rectangle area used by the application). 8 | * 9 | * @param stage the stage property of aDisplayObject
.
10 | *
11 | * @playerversion Flash 11
12 | * @playerversion AIR 3.0
13 | * @langversion 3.0
14 | *
15 | * @see http://www.adobe.com/devnet/air/articles/multiple-screen-sizes.html Supporting the multiple screen sizes of multiple devices in Adobe AIR
16 | */
17 | public function getViewportSize( stage:Stage ):String
18 | {
19 | var w:Number = stage.stageWidth;
20 | var h:Number = stage.stageHeight;
21 |
22 | return String(w) + "x" + String(h);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/isAIR.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 | import flash.system.Security;
4 |
5 | /**
6 | * Returns true
if the current context is an AIR application.
7 | *
8 | * @playerversion Flash 11
9 | * @playerversion AIR 3.0
10 | * @langversion 3.0
11 | */
12 | public function isAIR():Boolean
13 | {
14 | return Security.sandboxType == Security.APPLICATION;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/libraries/uanalytics/utils/isDigit.as:
--------------------------------------------------------------------------------
1 | package libraries.uanalytics.utils
2 | {
3 |
4 | /**
5 | * Indicates if the specified character is a digit.
6 | *
7 | * @param c The expression to evaluate.
8 | * @param index The optional index to evaluate a specific character in the
9 | * passed-in expression.
10 | *
11 | * @return True if the specified character is a digit.
12 | *
13 | * @playerversion Flash 11
14 | * @playerversion AIR 3.0
15 | * @playerversion AVM 0.4
16 | * @langversion 3.0
17 | */
18 | public function isDigit( c:String , index:uint = 0 ):Boolean
19 | {
20 | if( index > 0 )
21 | {
22 | c = c.charAt( index ) ;
23 | }
24 |
25 | return ("0" <= c) && (c <= "9");
26 | }
27 | }
--------------------------------------------------------------------------------
/src/uanalytics.as:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | include "C/unistd/which.as";
6 | include "crypto/generateRandomBytes.as";
7 |
8 | include "libraries/uanalytics/tracking/AnalyticsTracker.as";
9 | include "libraries/uanalytics/tracking/AnalyticsSender.as";
10 | include "libraries/uanalytics/tracking/Configuration.as";
11 | include "libraries/uanalytics/tracking/HitModel.as";
12 | include "libraries/uanalytics/tracking/HitSampler.as";
13 | include "libraries/uanalytics/tracking/HitSender.as";
14 | include "libraries/uanalytics/tracking/Metadata.as";
15 | include "libraries/uanalytics/tracking/RateLimiter.as";
16 | include "libraries/uanalytics/tracking/RateLimitError.as";
17 | include "libraries/uanalytics/tracking/Tracker.as";
18 |
19 | include "libraries/uanalytics/tracker/HitType.as";
20 | include "libraries/uanalytics/tracker/DataSource.as";
21 | include "libraries/uanalytics/tracker/SessionControl.as";
22 | include "libraries/uanalytics/tracker/ApplicationInfo.as";
23 | include "libraries/uanalytics/tracker/SystemInfo.as";
24 | include "libraries/uanalytics/tracker/TimingInfo.as";
25 | include "libraries/uanalytics/tracker/CommandLineTracker.as";
26 | include "libraries/uanalytics/tracker/CliTracker.as";
27 |
28 | include "libraries/uanalytics/tracker/senders/TraceHitSender.as";
29 | include "libraries/uanalytics/tracker/senders/BSDSocketHitSender.as";
30 | include "libraries/uanalytics/tracker/senders/CurlHitSender.as";
31 |
32 | include "libraries/uanalytics/utils/isDigit.as";
33 | include "libraries/uanalytics/utils/crc32.as";
34 | include "libraries/uanalytics/utils/getCLIHostname.as";
35 | include "libraries/uanalytics/utils/generateCLIUUID.as";
36 | include "libraries/uanalytics/utils/generateCLISystemInfo.as";
37 | include "libraries/uanalytics/utils/generateCLIUserAgent.as";
38 |
39 | include "libraries/uanalytics/tracker/addons/DebugFileSystemStorage.as";
40 |
41 | "uanalytics 0.8.0";
--------------------------------------------------------------------------------
/src/uanalytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zwetan/as3-universal-analytics/244b1e49e382d76c9202c3be69cee3aa40787217/src/uanalytics.png
--------------------------------------------------------------------------------
/src/version.properties:
--------------------------------------------------------------------------------
1 |
2 | version.major=0
3 | version.minor=8
4 | version.build=0
5 |
--------------------------------------------------------------------------------