diff --git a/Makefile b/Makefile index a1dfdc304a..f7f3df6798 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ $(PYTHON): $(MAKO_RENDER): $(PYTHON) $(API_DEPS): $(API_SHARED_INFO) $(API_DEPS_TPL) $(MAKO_LIB_FILES) $(MAKO_RENDER) - PYTHONPATH=$(MAKO_LIB_DIR) $(TPL) --template-dir '.' -io $(API_DEPS_TPL) --data-files $(API_SHARED_INFO) > $@ + PYTHONPATH=$(MAKO_LIB_DIR) $(TPL) --template-dir '.' -io $(API_DEPS_TPL)=$@ --data-files $(API_SHARED_INFO) api-deps: $(API_DEPS) diff --git a/etc/api/shared.yaml b/etc/api/shared.yaml index 8c5f288c22..e5fbfff4f7 100644 --- a/etc/api/shared.yaml +++ b/etc/api/shared.yaml @@ -13,6 +13,9 @@ api: - name: youtube version: v3 base_path: "etc/api" + terms: + # how to actually do something with the API + action: do templates: # all output directories are relative to the one set for the respective API - source: README.md diff --git a/gen/youtube3/README.md b/gen/youtube3/README.md index a214ff1014..9ff8020c6c 100644 --- a/gen/youtube3/README.md +++ b/gen/youtube3/README.md @@ -5,10 +5,75 @@ DO NOT EDIT ! --> The `youtube3` library allows access to all features of *YouTube*. -TODO: Library level fully fledged documentation, incuding **summary** and **usage**. -And another line, for testing +# Features -# Activities +Handle the following *Resources* with ease ... + +* activities (*insert* and *list*) +* channel banners (*insert*) +* channel sections (*delete*, *insert*, *list* and *update*) +* channels (*list* and *update*) +* guide categories (*list*) +* i18n languages (*list*) +* i18n regions (*list*) +* live broadcasts (*bind*, *control*, *delete*, *insert*, *list*, *transition* and *update*) +* live streams (*delete*, *insert*, *list* and *update*) +* playlist items (*delete*, *insert*, *list* and *update*) +* playlists (*delete*, *insert*, *list* and *update*) +* search (*list*) +* subscriptions (*delete*, *insert* and *list*) +* thumbnails (*set*) +* video categories (*list*) +* videos (*delete*, *getRating*, *insert*, *list*, *rate* and *update*) +* watermarks (*set* and *unset*) + +# Structure of this Library + +The API is structured into the following primary items: + +* **Hub** + * a central object to maintain state and allow accessing all *Activities* +* **Resources** + * primary types that you can apply *Activities* to + * a collection of properties and *Parts* + * **Parts** + * a collection of properties + * never directly used in *Activities* +* **Activities** + * operations to apply to *Resources* + +Generally speaking, you can invoke *Activities* like this: + +```Rust,ignore +let r = hub.resource().activity(...).do() +``` + +Or specifically ... + +```ignore +let r = hub.videos().rate(...).do() +let r = hub.videos().getRating(...).do() +let r = hub.videos().list(...).do() +let r = hub.videos().insert(...).do() +let r = hub.videos().update(...).do() +let r = hub.videos().delete(...).do() +``` + +The `resource()` and `activity(...)` calls create [builders][builder-pattern]. The second one dealing with `Activities` +supports various methods to configure the impending operation. It is made such that all required arguments have to be +specified right away (i.e. `(...)`), whereas all optional ones can be [build up][builder-pattern] as desired. +The `do()` method performs the actual communication with the server and returns the respective result. + +# Usage (*TODO*) + +## Instantiating the Hub + +## About error handling + +## About costumization + +[builder-pattern]: http://en.wikipedia.org/wiki/Builder_pattern +[google-go-api]: https://github.com/google/google-api-go-client # License diff --git a/gen/youtube3/src/lib.rs b/gen/youtube3/src/lib.rs index 7931074beb..b7f40d6b0c 100644 --- a/gen/youtube3/src/lib.rs +++ b/gen/youtube3/src/lib.rs @@ -2,10 +2,76 @@ // This file was generated automatically from 'src/mako/lib.rs.mako' // DO NOT EDIT ! -//! TODO: Library level fully fledged documentation, incuding **summary** and **usage**. -//! And another line, for testing +//! # Features +//! +//! Handle the following *Resources* with ease ... +//! +//! * activities (*insert* and *list*) +//! * channel banners (*insert*) +//! * channel sections (*delete*, *insert*, *list* and *update*) +//! * channels (*list* and *update*) +//! * guide categories (*list*) +//! * i18n languages (*list*) +//! * i18n regions (*list*) +//! * live broadcasts (*bind*, *control*, *delete*, *insert*, *list*, *transition* and *update*) +//! * live streams (*delete*, *insert*, *list* and *update*) +//! * playlist items (*delete*, *insert*, *list* and *update*) +//! * playlists (*delete*, *insert*, *list* and *update*) +//! * search (*list*) +//! * subscriptions (*delete*, *insert* and *list*) +//! * thumbnails (*set*) +//! * video categories (*list*) +//! * videos (*delete*, *getRating*, *insert*, *list*, *rate* and *update*) +//! * watermarks (*set* and *unset*) +//! +//! # Structure of this Library +//! +//! The API is structured into the following primary items: +//! +//! * **Hub** +//! * a central object to maintain state and allow accessing all *Activities* +//! * **Resources** +//! * primary types that you can apply *Activities* to +//! * a collection of properties and *Parts* +//! * **Parts** +//! * a collection of properties +//! * never directly used in *Activities* +//! * **Activities** +//! * operations to apply to *Resources* +//! +//! Generally speaking, you can invoke *Activities* like this: +//! +//! ```Rust,ignore +//! let r = hub.resource().activity(...).do() +//! ``` +//! +//! Or specifically ... +//! +//! ```ignore +//! let r = hub.videos().rate(...).do() +//! let r = hub.videos().getRating(...).do() +//! let r = hub.videos().list(...).do() +//! let r = hub.videos().insert(...).do() +//! let r = hub.videos().update(...).do() +//! let r = hub.videos().delete(...).do() +//! ``` +//! +//! The `resource()` and `activity(...)` calls create [builders][builder-pattern]. The second one dealing with `Activities` +//! supports various methods to configure the impending operation. It is made such that all required arguments have to be +//! specified right away (i.e. `(...)`), whereas all optional ones can be [build up][builder-pattern] as desired. +//! The `do()` method performs the actual communication with the server and returns the respective result. +//! +//! # Usage (*TODO*) +//! +//! ## Instantiating the Hub +//! +//! ## About error handling +//! +//! ## About costumization +//! +//! [builder-pattern]: http://en.wikipedia.org/wiki/Builder_pattern +//! [google-go-api]: https://github.com/google/google-api-go-client //! -//! # Activities //! //! #![feature(core)] diff --git a/src/mako/README.md.mako b/src/mako/README.md.mako index 32e1452d65..73f3b72b09 100644 --- a/src/mako/README.md.mako +++ b/src/mako/README.md.mako @@ -1,10 +1,13 @@ -<%! import util as pyutil %>\ +<% + from util import (markdown_comment, new_context) + c = new_context(resources) +%>\ <%namespace name="lib" file="lib/lib.mako"/>\ <%namespace name="util" file="lib/util.mako"/>\ -<%block filter="pyutil.markdown_comment">\ +<%block filter="markdown_comment">\ <%util:gen_info source="${self.uri}" />\ The `${util.library_name()}` library allows access to all features of *${canonicalName}*. -<%lib:docs /> +${lib.docs(c)} <%lib:license /> \ No newline at end of file diff --git a/src/mako/lib.rs.mako b/src/mako/lib.rs.mako index 2df1388273..819b832452 100644 --- a/src/mako/lib.rs.mako +++ b/src/mako/lib.rs.mako @@ -1,19 +1,18 @@ <% - import util - nested_schemas = list(util.iter_nested_types(schemas)) + from util import (iter_nested_types, new_context, rust_comment, rust_module_doc_comment, ) + nested_schemas = list(iter_nested_types(schemas)) - sta_map, fqan_map = util.build_activity_mappings(resources) - c = util.Context(sta_map, fqan_map) + c = new_context(resources) %>\ <%namespace name="lib" file="lib/lib.mako"/>\ <%namespace name="mutil" file="lib/util.mako"/>\ <%namespace name="schema" file="lib/schema.mako"/>\ -<%block filter="util.rust_comment">\ +<%block filter="rust_comment">\ <%mutil:gen_info source="${self.uri}" />\ -<%block filter="util.rust_module_doc_comment">\ -<%lib:docs />\ +<%block filter="rust_module_doc_comment">\ +${lib.docs(c)} #![feature(core)] #![allow(non_snake_case)] diff --git a/src/mako/lib/lib.mako b/src/mako/lib/lib.mako index c1281b08b2..65319e8918 100644 --- a/src/mako/lib/lib.mako +++ b/src/mako/lib/lib.mako @@ -1,17 +1,79 @@ -<%! import util %>\ -<%namespace name="util" file="lib/util.mako"/>\ +<%! from util import (activity_split, put_and, md_italic, split_camelcase_s) %>\ +<%namespace name="util" file="util.mako"/>\ -<%def name="docs()">\ -TODO: Library level fully fledged documentation, incuding **summary** and **usage**. -And another line, for testing +<%def name="docs(c)">\ +<% + # fr == fattest resource, the fatter, the more important, right ? + fr = None + fr = sorted(schemas.values(), key=lambda s: (len(c.sta_map.get(s.id, [])), len(s.get('properties', []))), reverse=True)[0] -# Activities + # resouce -> [activity, ...] + amap = dict() + for an in c.fqan_map: + resource, activity = activity_split(an) + amap.setdefault(resource, list()).append(activity) +%>\ +# Features + +Handle the following *Resources* with ease ... + +% for r in sorted(amap.keys()): +* ${split_camelcase_s(r)} (${put_and(md_italic(sorted(amap[r])))}) +% endfor + +# Structure of this Library + +The API is structured into the following primary items: + +* **Hub** + * a central object to maintain state and allow accessing all *Activities* +* **Resources** + * primary types that you can apply *Activities* to + * a collection of properties and *Parts* + * **Parts** + * a collection of properties + * never directly used in *Activities* +* **Activities** + * operations to apply to *Resources* + +Generally speaking, you can invoke *Activities* like this: + +```Rust,ignore +let r = hub.resource().activity(...).${api.terms.action}() +``` + +Or specifically ... + +```ignore +% for an, a in c.sta_map[fr.id].iteritems(): +<% + resource, activity = activity_split(an) +%>\ +let r = hub.${resource}().${activity}(...).${api.terms.action}() +% endfor +``` + +The `resource()` and `activity(...)` calls create [builders][builder-pattern]. The second one dealing with `Activities` +supports various methods to configure the impending operation. It is made such that all required arguments have to be +specified right away (i.e. `(...)`), whereas all optional ones can be [build up][builder-pattern] as desired. +The `${api.terms.action}()` method performs the actual communication with the server and returns the respective result. + +# Usage (*TODO*) + +${'##'} Instantiating the Hub + +${'##'} About error handling + +${'##'} About costumization + +[builder-pattern]: http://en.wikipedia.org/wiki/Builder_pattern +[google-go-api]: https://github.com/google/google-api-go-client <%def name="license()">\ # License -The **${util.library_name(name, version)}** library was generated by ${util.put_and(copyright.authors)}, and is placed +The **${util.library_name()}** library was generated by ${put_and(copyright.authors)}, and is placed under the *${copyright.license_abbrev}* license. You can read the full text at the repository's [license file][repo-license]. diff --git a/src/mako/lib/schema.mako b/src/mako/lib/schema.mako index f4d913b2ed..f442fba9b1 100644 --- a/src/mako/lib/schema.mako +++ b/src/mako/lib/schema.mako @@ -1,12 +1,12 @@ -<%! import util %>\ +<%! from util import (schema_markers, rust_doc_comment, mangle_ident, to_rust_type, put_and, IO_TYPES, activity_split) %>\ ## Create new schema with everything. ## 's' contains the schema structure from json to build <%def name="new(s, c)">\ <% assert s.type == "object" - markers = util.schema_markers(s, c) + markers = schema_markers(s, c) %>\ -<%block filter="util.rust_doc_comment">\ +<%block filter="rust_doc_comment">\ ${doc(s, c)}\ #[derive(RustcEncodable, RustcDecodable, Default, Clone)] @@ -14,8 +14,8 @@ pub struct ${s.id}\ % if 'properties' in s: { % for pn, p in s.properties.iteritems(): - ${p.get('description', 'no description provided') | util.rust_doc_comment} - pub ${util.mangle_ident(pn)}: ${util.to_rust_type(s.id, pn, p)}, + ${p.get('description', 'no description provided') | rust_doc_comment} + pub ${mangle_ident(pn)}: ${to_rust_type(s.id, pn, p)}, % endfor } % else: @@ -34,10 +34,10 @@ ${s.get('description', 'There is no detailed description.')} # Activities This type is used in activities, which are methods you may call on this type or where this type is involved in. -The list links the activity name, along with information about where it is used (one of ${util.put_and(list('*%s*' % t - for t in util.IO_TYPES))}). +The list links the activity name, along with information about where it is used (one of ${put_and(list('*%s*' % t + for t in IO_TYPES))}). -${''.join("* %s (%s)\n" % (util.activity_split(a)[1], iot and '|'.join(iot) or 'none') +${''.join("* %s (%s)\n" % (activity_split(a)[1], iot and '|'.join(iot) or 'none') for a, iot in c.sta_map[s.id].iteritems())} % else: diff --git a/src/mako/lib/util.py b/src/mako/lib/util.py index c1454dc27f..9119948ce2 100644 --- a/src/mako/lib/util.py +++ b/src/mako/lib/util.py @@ -69,6 +69,13 @@ def put_and(l): return l[0] return ', '.join(l[:-1]) + ' and ' + l[-1] +def md_italic(l): + return ['*%s*' % s for s in l] + +def split_camelcase_s(s): + s1 = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', s) + return re.sub('([a-z0-9])([A-Z])', r'\1 \2', s1).lower() + ## -- End Natural Language Utilities -- @} @@ -237,6 +244,11 @@ def activity_name_to_type_name(an): Context = collections.namedtuple('Context', ['sta_map', 'fqan_map']) +# return a newly build context from the given data +def new_context(resources): + sta_map, fqan_map = build_activity_mappings(resources) + return Context(sta_map, fqan_map) + # Expects v to be 'v\d+', throws otherwise def to_api_version(v): assert len(v) >= 2 and v[0] == 'v'