Blog

  • cordova-plugin-aliyun-push

    Visit original content creator repository
    https://github.com/liuxiaoy/cordova-plugin-aliyun-push

  • darg

    D Argument Parser Build Status

    Better command line argument parsing using D’s powerful compile-time code generation facilities.

    Note: This is a stable library, but it is no longer maintained. If you’d like to help out with maintanence please make an issue letting me know!

    Example

    import std.stdio;
    import darg;
    
    struct Options
    {
        @Option("help", "h")
        @Help("Prints this help.")
        OptionFlag help;
    
        @Option("threads", "t")
        @Help("Number of threads to use.")
        size_t threads;
    
        @Argument("file", Multiplicity.zeroOrMore)
        @Help("Input files")
        string[] files;
    }
    
    // Generate the usage and help string at compile time.
    immutable usage = usageString!Options("example");
    immutable help = helpString!Options;
    
    int main(string[] args)
    {
        Options options;
    
        try
        {
            options = parseArgs!Options(args[1 .. $]);
        }
        catch (ArgParseError e)
        {
            writeln(e.msg);
            writeln(usage);
            return 1;
        }
        catch (ArgParseHelp e)
        {
            // Help was requested
            writeln(usage);
            write(help);
            return 0;
        }
    
        foreach (f; options.files)
        {
            // Use files
        }
    
        return 0;
    }
    $ ./example --help
    Usage: example [--help] [--threads=<ulong>] [file...]
    
    Positional arguments:
     file            Input files
    
    Optional arguments:
     --help, -h      Prints this help.
     --threads, -t <ulong>
                     Number of threads to use.
    
    $ ./example --foobar
    Unknown option '--foobar'
    Usage: program [--help] [--threads=<ulong>] [file...]
    

    License

    MIT License

    Visit original content creator repository https://github.com/jasonwhite/darg
  • secondhand-auction

    Secondhand-Auction

    πŸ“Œ ν”„λ‘œμ νŠΈ λͺ©ν‘œ

    • 객체지ν–₯ 섀계원칙에 따라 RESTful API λ₯Ό 섀계 ν•©λ‹ˆλ‹€.

    • TDDκ°œλ°œλ‘ μ„ μ μš©ν•˜λ©°, ν…ŒμŠ€νŠΈμ˜ μ€‘μš”μ„±μ— λŒ€ν•΄ ν•™μŠ΅ν•©λ‹ˆλ‹€.

    • λŒ€μš©λŸ‰ νŠΈλž˜ν”½κ³Ό λ™μ‹œμ„±μ— λŒ€ν•΄ κ³ λ €ν•˜λ©° κ°œλ°œν•©λ‹ˆλ‹€.

    • μƒˆλ‘œμš΄ 컀밋이 λ°œμƒν•  λ•Œ λ§ˆλ‹€ μ½”λ“œλ¦¬λ·°λ₯Ό 톡해 λ¦¬νŒ©ν† λ§μ΄ ν•„μš”ν•œ 뢀뢄을 μ°Ύμ•„λ‚΄κ³ , κ°œμ„ ν•©λ‹ˆλ‹€.


    βœοΈν”„λ‘œμ νŠΈ νŠΉμ§•

    κ΅¬ν˜„ν•˜κ³  싢은 κΈ°λŠ₯

    μ‚¬μš©μžκ°€ μ°Έμ—¬ν•˜κ³  μžˆλŠ” κ²½λ§€ λˆ„κ΅°κ°€ μž…μ°° ν–ˆμ„ λ•Œ, 경맀에 μ°Έκ°€ν•œ μ‚¬μš©μžλ“€μ—κ²Œ μƒˆλ‘œμš΄ μž…μ°° λ°œμƒ λ©”μ‹œμ§€λ₯Ό 보내고, 접속쀑인 μ‚¬μš©μžμ—κ²ŒλŠ” μ‹€μ‹œκ°„μœΌλ‘œ μ•Œλ¦Όμ„ λ³΄λ‚΄λŠ” κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ³ μž ν–ˆμŠ΅λ‹ˆλ‹€.

    문제

    • μƒˆλ‘œμš΄ μž…μ°° λ°œμƒ λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ” μž‘μ—…μ€ DB에 μ ‘κ·Ό ν•΄ Insert 쿼리 호좜 ν•΄μ•Όν•˜κ³ , μ‹€μ‹œκ°„ μ•Œλ¦Όμ„ λ°œμ†‘ν•˜κΈ° μœ„ν•΄ Websocket 을 μ‚¬μš©ν•΄ μ ‘μ†ν•œ λŒ€μƒμ„ 체크해 μ•ŒλžŒμ„ 보내야 ν–ˆμŠ΅λ‹ˆλ‹€. κ²½λ§€ μ°Έμ—¬μžκ°€ 증가할 수둝, μž…μ°° 둜직 μˆ˜ν–‰μ‹œκ°„ 보닀 λ©”μ‹œμ§€μ™€ μ‹€μ‹œκ°„ μ•Œλ¦Όμ„ λ³΄λ‚΄κΈ°μœ„ν•œ λŒ€κΈ°μ‹œκ°„μ΄ κΈΈμ–΄μ‘ŒμŠ΅λ‹ˆλ‹€.

    ν•΄κ²°λ°©μ•ˆ 및 κ²°κ³Ό

    • κ²½λ§€ μ°Έμ—¬μžκ°€ λ§Žμ•„μ§ˆ κ²½μš°μ—λ„ μž…μ°° 둜직의 μˆ˜ν–‰μ‹œκ°„μ„ λ³΄μ‘΄ν•˜κ³ μž λ©€ν‹°λͺ¨λ“ˆμ„ ν™œμš©, μž…μ°° λ‘œμ§μ„ μˆ˜ν–‰ν•˜λŠ” μ„œλ²„μ™€ κ²½λ§€ μ•Œλ¦Ό λ‘œμ§μ„ μˆ˜ν–‰ν•˜λŠ” μ„œλ²„λ₯Ό 뢄리해 μˆ˜ν–‰ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.
      • κ²½λ§€ μ°Έμ—¬μžκ°€ λ§Žμ•„μ§ˆ κ²½μš°μ—λ„, κ²½λ§€ 등둝 λ‘œμ§μ€ 100ms μ΄λ‚΄λ‘œ μˆ˜ν–‰λ  수 μžˆμŠ΅λ‹ˆλ‹€.
      • 핡심 둜직(κ²½λ§€) 이외 λ¬Έμ œκ°€ λ°œμƒν•˜λ”λΌλ„, λ©”μΈμ„œλ²„μ˜ μ•ˆμ •μ„±μ„ 보μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
      • μ„œλ²„ ν™•μž₯이 ν•„μš”ν•  λ•Œ, νŠΈλž˜ν”½μ΄ λͺ°λ¦¬λŠ” νŠΉμ • μ„œλ²„μ— λŒ€ν•΄μ„œλ§Œ ν™•μž₯이 κ°€λŠ₯ν•΄ λΉ„μš© νš¨μœ¨μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
      • κΈ°λŠ₯λ³€κ²½ 및 κ°œμ„  μž‘μ—…μ΄ μ΄λ£¨μ–΄μ§ˆ λ•Œ, λ‹€λ₯Έμ„œλ²„에 λ―ΈμΉ˜λŠ” 영ν–₯을 μ΅œμ†Œν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    문제

    • ν•œ κ°€μ§€ κΈ°λŠ₯을 μœ„ν•΄, μ—¬λŸ¬κ°œμ˜ μ„œλ²„μ—μ„œ μž‘μ—…μ΄ 이루어져야 ν–ˆμŠ΅λ‹ˆλ‹€.
    • μ„œλ²„κ°€ 물리적으둜 κ²°ν•©λ˜μ–΄ μžˆμ–΄, μ™ΈλΆ€μ—μ„œ μ„œλ²„μ˜ ꡬ쑰λ₯Ό νŒŒμ•…ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
    • μ„œλ²„κ°€ λ‹€μš΄λ˜κ±°λ‚˜ λ§Žμ€ μš”μ²­μ΄ λͺ°λ¦¬λ”라도, λ©”μ‹œμ§€ 손싀이 λ°œμƒν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

    ν•΄κ²°λ°©μ•ˆ 및 κ²°κ³Ό

    • μ„œλ²„μ˜ 연결을 λ©”μ‹œμ§€ 큐(AWS SQS)λ₯Ό 톡해 λ°œν–‰, ꡬ독 ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.
      • μ—¬λŸ¬ μ„œλ²„μ—μ„œ μž‘μ—…μ΄ λΉ„λ™κΈ°μ μœΌλ‘œ 이루어 질 수 μžˆμ–΄, μ‹œμŠ€ν…œμ˜ μ²˜λ¦¬λŸ‰μ„ μ¦κ°€μ‹œν‚€κ³  μ‚¬μš©μžμ—κ²Œ λΉ λ₯Έ μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
      • 각 μ„œλ²„κ°€ 물리적 결합이 μ•„λ‹Œ κ°„μ ‘μ μœΌλ‘œ ν†΅μ‹ λ˜λ―€λ‘œ, μ™ΈλΆ€μ—μ„œ ꡬ쑰λ₯Ό νŒŒμ•…ν•  수 μ—†κ²Œ ν•΄ λ³΄μ•ˆμ μœΌλ‘œ μ•ˆμ „ν•˜κ²Œ μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
      • μ„œλ²„κ°€ λ‹€μš΄λ˜κ±°λ‚˜ λ§Žμ€ μš”μ²­μ΄ λͺ°λ¦¬λ”라도, 큐λ₯Ό 톡해 λ©”μ‹œμ§€κ°€ κ΄€λ¦¬λ˜μ–΄, λ©”μ„Έμ§€ 손싀 없이 μ•ˆμ •μ μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    πŸ’‘ μ€‘κ³ κ±°λž˜ μ˜₯μ…˜ μ„œλ²„ ꡬ쑰도

    img_server_structure.png

    • ECS Fargateλ₯Ό μ΄μš©ν•΄ Main, Sender, Broker 3개의 μ„œλΉ„μŠ€λ₯Ό λ„μš°κ³ , ALB 섀정을 톡해 /sender/* 둜 μš”μ²­ λ˜λŠ” 건에 λŒ€ν•΄μ„œλŠ” Notification Sender μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μœΌλ‘œ, λ‚˜λ¨Έμ§€ μš”μ²­μ€ Main μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μœΌλ‘œ μš”μ²­λ˜λ„λ‘ κ΅¬μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

    • Redis μ„œλ²„λŠ” ElastiCache λ₯Ό ν™œμš©ν•˜λ©°, Main μ„œλ²„μ—μ„œμ˜ 둜그인 μ„Έμ…˜ 곡유, μΊμ‹±μ²˜λ¦¬, μž…μ°° μ‹œ λ™μ‹œμ„± μ œμ–΄λ₯Ό μœ„ν•œ Lock 으둜 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

    • AWS SQSλ₯Ό ν™œμš©ν•΄ Main μ„œλ²„μ™€ Broker μ„œλ²„ κ°„μ˜ λ©”μ‹œμ§€ 전달, Sender μ„œλ²„μ™€ Broker μ„œλ²„ κ°„μ˜ λ©”μ‹œμ§€ 전달을 κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.


    πŸ“Œ κ²½λ§€μš”μ²­ μ‹œν€€μŠ€ λ‹€μ΄μ–΄κ·Έλž¨

    img_bidding_sequence.png

    • 둜그인 μ‹œ, 고객은 Sender μ„œλ²„μ™€ Websocket 을 톡해 μ—°κ²°μƒνƒœλ₯Ό μœ μ§€ν•©λ‹ˆλ‹€.

    • 고객이 μž…μ°° μ‹œ, Main μ„œλ²„μ—μ„œλŠ” ν•΄λ‹Ή μš”μ²­μ„ λ°›μ•„ μž…μ°°λ‘œμ§μ„ μˆ˜ν–‰ν•˜κ³ , AWS SQS(sha-message-queue)에 κ²½λ§€ 정보 λ©”μ‹œμ§€λ₯Ό Publish ν•©λ‹ˆλ‹€.

    • Broker μ„œλ²„μ—μ„œλŠ” AWS SQS(sha-message-queue)에 λ©”μ‹œμ§€λ₯Ό λ°›μ•˜μ„ λ•Œ, κ²½λ§€ μ°Έμ—¬μžμ˜ λ©”μ‹œμ§€ν•¨μ— λ©”μ‹œμ§€λ₯Ό μΆ”κ°€ν•˜κ³ , μ•ŒλžŒμ„ μœ„ν•œ 정보λ₯Ό AWS SQS( sha-message-send-queue) 둜 Publish ν•©λ‹ˆλ‹€.

    • Sender μ„œλ²„μ—μ„œλŠ” AWS SQS(sha-message-send-queue)에 λ©”μ‹œμ§€λ₯Ό λ°›μ•˜μ„ λ•Œ, Websocket 을 톡해 μ‹€μ‹œκ°„ μ•ŒλžŒμ„ μ „μ†‘ν•©λ‹ˆλ‹€.


    πŸ“Œ Secondhand-Auction μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ 및 CI/CD ꡬ쑰도

    img_cicd_structure.png

    • ν”„λ‘œμ νŠΈμ˜ 역할을 λΆ„λ¦¬ν•˜κΈ° μœ„ν•΄ λ©€ν‹°λͺ¨λ“ˆμ„ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” κΈ°λŠ₯듀을 common λͺ¨λ“ˆλ‘œ κ΅¬λΆ„ν•œ λ’€ ν•΄λ‹Ή λͺ¨λ“ˆμ„ μ‚¬μš©ν•΄ mainκ³Ό broker μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν–ˆκ³ , μ‹€μ‹œκ°„ μ•ŒλžŒμ„ μœ„ν•œ SenderλŠ” λ”°λ‘œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

    • TeamCity 의 VCS Trigger λ₯Ό 톡해 Github Main 브런치의 컀밋 이벀트λ₯Ό κ°μ§€ν•˜κ³ , ν•΄λ‹Ή μ΄λ²€νŠΈμ— λŒ€ν•΄ λΉŒλ“œ 및 ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ ν›„ Docker 이미지λ₯Ό ꡬ성해 ECR둜 μ—…λ‘œλ“œν•©λ‹ˆλ‹€.

    • μ—…λ‘œλ“œ 된 Docker 이미지λ₯Ό ECS Fargate 에 λ°°ν¬ν•˜κ³ , ALB λ₯Ό 톡해 μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.


    Visit original content creator repository https://github.com/f-lab-edu/secondhand-auction
  • Zombie-DDoS

    Zombie-DDoS

    A toolkit to perform Distributed Denial of Service Attack using windows system, for which I designed a worm that embeds into windows startup upon it’s first trigger. And then after will automatically start whenever the system is turned on.

    Installing and getting started

    Configure Server (Control Panel)

    • It’s really simple to start with, just go ahead and clone the repository on a windows machine.
    • Now configure your PHP server from where you can keep an eye on systems that are infected by this Worm.
    • Do copy all the php files in server directory to suitable hosted directory on your server.

    Building the worm

    • Now run zombie.cpp in any suitable C++ compiler.
    • Do remember to replace SERVER_URL macro definition with link of your server.
    • This will register zombie executable file to startup folder making sure that program is triggered upon windows boot.
    • This executable can be shared on different windows system and for all these notorious zombies, you have the control.

    Working with the control panel interface

    ezgif com-crop

    • The interface is quite simple to use.
    • Enter the site you want to attack and ping limit (iterations).
    • Woohooo, all your zombies on windows system through out the world are doing nasty stuff for you.
    • Soon, if number of live bots are enough, the site will go down.

    Example

    • A sample version is hosted on here

    Future Ideas

    • Further I want to make the worm more independent.
    • It must have cloning and self replicating properties.
    • Also encrypt it, making it very difficult to trace.
    • And many more mischievous ideas.

    Contribution

    • Please feel free to raise issues.
    • Pull Requests are utmost welcomed.
    Visit original content creator repository https://github.com/saurass/Zombie-DDoS
  • aws-deployment-framework

    AWS Deployment Framework

    Build Status

    MegaLinter

    The AWS Deployment Framework (ADF) is an extensive and flexible framework to manage and deploy resources across multiple AWS accounts and regions within an AWS Organization.

    ADF allows for staged, parallel, multi-account, cross-region deployments of applications or resources via the structure defined in AWS Organizations while taking advantage of services such as AWS CodePipeline, AWS CodeBuild, and AWS CodeCommit to alleviate the heavy lifting and management compared to a traditional CI/CD setup.

    ADF allows for clearly defined deployment and approval stages which are stored in a centralized configuration file. It also allows for account based bootstrapping, by which you define an AWS CloudFormation template and assign it to a specific Organization Unit (OU) within AWS Organizations. From there, any account you move into this OU will automatically apply this template as its baseline.

    Quick Start

    • Refer to the Installation Guide for Installation steps.
    • Refer to the Admin Guide on guidance how-to manage and administrate ADF.
    • Refer to the User Guide for using ADF to generate and manage pipelines.
    • Refer to the Technical Guide if you want to learn more about the inner workings of ADF. For example in case you want to contribute or build on top of ADF.
    • Refer to the Samples Guide for a detailed walk through of the provided samples.
    • Refer to the Multi-Organization ADF Setup to use ADF in an enterprise-grade setup.
    Visit original content creator repository https://github.com/awslabs/aws-deployment-framework
  • Food-Ordering-System-

    Food-Ordering-System-

    This system can be used in any ordering place, as it uses Queue data structure which follows FIFO sequence with enquing and dequing as main functions.


    Title:

    Food Ordering System

    Introduction:

    The purpose of this project is to develop a food ordering system that can be used to transform the traditional ordering system. Generally, in restaurants menu order system is actual provided in menu card format so the customer must select the menu item then the waiter must come and take the order, which is a long processing method. So, I have designed Food Ordering System that displays food items for customers on their available devices such as user phone, Tablet etc. to give input their orders directly by touching.

    The system automatically completes data display, receiving, sending, storage of data and analysis. It is providing many advantages as great user-friendly, saving time, portability, reduce human error, flexibility and provide customer feedback etc. This system required large numbers of manpower to handle customer reservation, ordering food, reminding dishes of customer. β€œIntelligent Automated Restaurant” it is all about getting all your different touchpoints working together connected, sharing information, speeding processes, and personalizing experiences. E-menu is an interactive ordering system with new digital menu for customers.

    Solution Approach:

    The digital world is vast, with limitless boundary. And it does not have to make anyone wait. And that’s the very reason, I have decided to make a food ordering system. This is done by using Python. The menu is programmed at backend to be displayed to user. Queue Data Structure is used to take the order and dispatch it to costumers by using First-In-First-Out (FIFO) method. The software generates the bill as well.

    Project Features:

    Operating System: Windows

    IDE(s): Google Collaboratory

    Data Structure: Queue

    Programming Language: Python

    Data Structure:

    Queue Data Structure is used in this project, due to the real-life depiction of food ordering system. When the customer(user) places an order, he or she must wait to get the order. Order placing is done by enqueue function and dispatchment of order is done by dequeue.

    Time Complexity:

    • The time complexity of enqueuing and dequeuing single order item O (1).
    • The time complexity of enqueuing and dequeuing multiple order item O(n).

    Functional specification:

    Food ordering software is having many modules, which make the software more efficient and user friendly.

    Modules:

    • Main Menu
    • Food items
    • Drinks item
    • Desserts
    • Check cart
    • Payment
    • Exit

    Screenshots:

    Menu

    image

    Flavor

    image

    Size and Quantity

    image

    Order Placed in Queue

    image

    Burger menu and Choice

    image

    Fries’ menu

    image

    Dessert’s menu

    image

    Drinks menu

    image

    Checking Cart / Order Queue

    image

    Payment

    image

    image

    Applications:

    This software can be used in any part of food industry such as:

    • Hotels
    • Restaurants
    • Mess
    • Canteens
    • Grocery stores
    • Food store

    Future work:

    Following section describe the work that will be implemented with future release of the software:

    • Customize orders: Allow customers to customize food order.
    • Enhance user interface by adding more user interactives futures: Provide deals and promotional offers, Provide recipes of the day.
    • Payment options: PayPal, Gifts cards etc.
    • Delivery option.
    • Visual graphical order status bar.
    • Show only active order to employees.
    • Restaurant locator.
    Visit original content creator repository https://github.com/Haseeeb21/Food-Ordering-System-
  • myHouse

    [MyHouse]

    Features

    • Collect data from a number of sensors by leveraging a simple to customize plugin-based architecture
    • Automatic calculation of hourly and daily minimum/maximum/average values for each sensor
    • Fully customizable web interface with mobile support to display the sensors’ statistics, control actuators and present custom data
    • Natural-language interactive Slack bot for remotely retrieving any statistic, send commands or just having fun
    • Speech recognition and text-to-speech capabilities for realtime voice interaction
    • Alerting module generating e-mails or Slack notifications whenever a configured condition is met
    • Daily e-mail digests containing all the UI widgets configured for the requeted module

    How it works

    Think of myHouse as a framework for automating your house. The first step is to configure the sensors you want to collect data from. Included in the package, there are already a number of plugins (e.g. to collect weather statistics, information from the linux box when it runs, retrieving images from the Internet, your GPS position from icloud, data collected by Wirelessthings/Ciseco sensors, interacting with the GPIO, leveraging rtl_433, etc.) and you can easily add your own plugins.
    Once your sensors are configured and data has been collecting, the suite automatically calculates for every hour and for every day minimum/maximum/average values so to present only summarized information without overloading with unnecessary data.

    What will be presented in the web interface is completely up to you. You can define your own modules, chose your icons and configure all the widgets that will be presented in the order you like the most. The statistics elaborated by the tool can be presented in a number of ways: timeline charts for different group of sensors with recent or historical data, current measures and minimum/maximum values for today and yesterday are just some of the examples. From the interface your actuators can be controlled as well: thanks to input fields, switches and a fully-featured scheduler, you can meet easily whatever requirements you might have.

    Collecting and presenting statistics is nice but you may want to be automatically alerted whenever a specific situation is taking place. This is why you can easily create rules which will trigger when the set of conditions you have defined will be all true. Actions can be configured as well to e.g. send a message to an actuator or just set the value of a sensor. An alert does not necessarily represent a critical situation but can be just a simple messages (e.g. the minimum and maximum temperature we had yesterday indoor) to share with the users. Notificationscan be presented within the web interface, sent by e-mail or sms, sent to a speacker or posted on a Slack channel of your choice.

    If you don’t know what Slack is, have a look at it. This collaborative, real-time messaging tool can become your family’s virtual place when enhanced by myHouse. Not only myHouse’s Slack bot will notify the members when something is happening but allows direct interaction in your natural language. Depending on your questions and what the bot knows (e.g. the attached sensors and configured widgets), it can reply by sharing with you its statistics and charts or send commands to an actuator on your behalf. The same mechanism applies if you connect a speaker and a microphone to the station: the bot will be able to understand your requests and respond accordingly.

    How I configured myHouse at home

    Since myHouse is a framework, everything is defined in the configuration file so my instance may look completely different than yours. This is nice because allows great flexibility but requires a starting point if you don’t want to get lost in the configuration. For this reason, I’m making my own configuration part of the distribution package under the name config-advanced.json: most of the modules and rules are disabled since do not necessarily work in your environment but at least you have a fully working example to take inspiration from.
    In my own myHouse, I have configured the following sensors:

    • Pressure, temperature, ambient light and humidity from Wirelessthings/Ciseco sensors
    • Forecast, weather condition, temperature, wind, rain/snow from Weather Underground
    • Weather alerts from Weather Channel
    • GPS position of the family’s members from icloud
    • Snapshots from multiple indoor and outdoor webcams
    • A number of system statistics from the raspberry pi hosting the application
    • Radio sensors from my legacy alarm system using rtl_433
    • A PIR sensor attached to the raspberry GPIO
    • Earthquake events from usgs as well as our local entity

    I have configured then the following modules and widgets:

    • Dashboard
      • A selection of the most interesting widgets from the other modules
    • Outdoor:
      • Forecast of the next 5 days, temperature ranges, weather conditions, chance of rain and snow
      • External temperature summary with current weather condition, minimum/maximum of today, yesterday, record and normal temperatures
      • External temperature recent (with hourly minimum/average/maximum) and historical (with daily minimum/average/maximum) timeline with weather condition
      • Historical precipitation timeline
      • Wind current measure, summary of today/yesterday, recent and historical timeline charts
      • Humidity current measure, summary of today/yesterday, recent and historical timeline charts
      • Ambient Light current measure, summary of today/yesterday, recent and historical timeline charts
      • Pressure current measure, summary of today/yesterday, recent and historical timeline charts
    • Indoor:
      • Internal temperature summary, minimum/maximum of today, yesterday for each room
      • Internal temperature recent (with hourly minimum/average/maximum) and historical (with daily minimum/average/maximum) timeline
      • Humidity current measure, summary of today/yesterday, recent and historical timeline charts
      • Fridge and refrigerator current temperature, summary of today/yesterday, recent and historical timeline charts
      • Battery status of the different sensors
    • Webcams:
      • Internet webcams as well as webcams I have indoor and outdoor
    • Location
      • Map with the GPS location of all the members of the family automatically generated by leveraging the “Where is my iphone?” API
    • Earthquakes
      • Map with relevant earthquakes collected from multiple sources
    • Boiler
      • Boiler status, manual switch to power it on/off and target temperature to reach while on
      • Calendar to schedule when the boiler has to automatically turns on and off
    • Irrigation
      • Irrigation status, manual switch to turn it on/off in each zone
      • Calendar to schedule when the irrigation has to automatically turns on and off
    • Alarm
      • Alarm status and manual switch to arm the system which is automatically set to the status of the physical alarm main unit
      • PIRs, smoke detectors, gas detectors, magnetic sensors. Each sensor can be armed indivirually and reports the last time it has triggered
    • System Status:
      • CPU current measure, summary of today/yesterday, recent and historical timeline charts
      • Memory current measure, summary of today/yesterday, recent and historical timeline charts
      • System load current measure, summary of today/yesterday, recent and historical timeline charts
      • Network Connections and services current measure, summary of today/yesterday, recent and historical timeline charts
      • Raspberry’s current temperature, summary of today/yesterday, recent and historical timeline charts
      • Database size current measure and historical timeline chart
    • Local Network:
      • Dnsmasq DHCP current leases, static DNS and DHCP mapping (my raspberry acts as a DNS/DHCP server)
    • Log Analysis:
      • Daily Logwatch output
    • Reboot/shutdown:
      • To reboot or shutdown the raspberry pi hosting the application
    • Logs:
      • myHouse logs and system logs
    • Configuration:
      • myHouse configuration module

    I have finally configured the following rules:

    • Outdoor module:
      • Weather alerts
      • Yesterday maximum/minimum temperature above or below the record for that day or the expected normal temperature
      • Yesterday maximum/minimum/average temperature the lowest/highest of the last few days
      • Forecast weather for tomorrow
    • Indoor module:
      • Yesterday maximum/minimum/average temperature the lowest/highest of the last few days
      • Temperature inside too high or too low
      • Fridge/Refrigerator temperature too high
      • Flood alert
    • Earthquake module:
      • A strong or close earthquake taking place
    • System module:
      • CPU utilization/System load/temperature too high
    • Boiler module:
      • Turning the boiler on/off when scheduled, requested, or when the indoor temperature is too low/high
    • Irrigation module:
      • Turning the irrigation on/off when scheduled
    • Alarm module:
      • Arm/disarm the system when the main legacy unit is armed/disarmed, notify when an armed sensor has triggered while the alarm is armed

    I have eventually configured a number of rules without conditions (that are used by the bot for its basic knowledge) reporting upon current weather conditions, temperature, boiler status, etc.

    Installing

    • Unzip the package and move its contents to a directory of your choice on your raspberry Pi (e.g. /opt/myHouse)
    • Run the installation script as root (e.g. sudo python /opt/myHouse/install.py) which will:
      • download and install all the required dependencies
      • create a service script, copy into /etc/init.d/myHouse and configured it to start at boot time
      • start the service
    • Access the web interface (e.g. http://your-raspberry-pi.ip)

    Installation logs will be made available under logs/install.log

    Uninstalling

    • Run as root the installation script with the “-u” parameter (e.g. sudo /opt/myHouse/install.py -u) which will:
      • stop the service
      • remove the service script from /etc/init.d/myHouse

    The dependencies, the database and all the other files belonging to myHouse will NOT be deleted.

    Upgrading

    • Stop the service
    • Copy the files of the new version in the directory where myHouse is installed, overwriting the existing files or run git pull if you had cloned the repository
    • Run as root the install.py script which will install the missing dependencies
    • Run as root the upgrade.py script which will upgrade your config.json file
    • A backup copy of the configuration file and the database will be saved under the tmp directory
    • Start the service

    Configuring

    The entire configuration of the suite is within the config.json file, of course in a JSON format (http://www.json.org/). If the file does not exist, at the first run, myHouse will automatically create one as a copy of config-example.json. This is a working example with basic functionalities.

    For a more complex example, the one described in the section above, review the config-advanced.json and take inspiration from there to understand the most complex capabilities of myHouse.

    The configuration itself is pretty articulated this is why it is highly recommended to review the config-schema.json file for a detailed explanation of the different options and combinations available. Alternatively, the configuration editor available from within the web interface allows to build your own configuration graphically (upon saving, a copy of the previous configuration is stored into the config.bak file). Either way, the resulting file is checked against the schema to ensure the configuration is correct upon startup. A service restart (e.g. sudo /etc/init.d/myHouse restart) is required to apply any change.

    The logic behind the configuration file is pretty simple: there is a generic configuration first (where the database is, what is the mailserver, which recipient to send notifications to, how to connect to Slack, what and where to log, etc.) followed by a number of custom modules. Each module is an entry in the menu of the web interface and has three main sections:

    • sensors: array of sensors belonging to the module. Each sensor includes the following information:
      • a group ID, sensors belonging to the same group can be presented within the same widget
      • a data structure to instruct the plugin to retrieve the data for the sensor, including the polling interval
      • a set of chart series (highcharts properites) that will be used when representing the chart in the web interface
    • widgets: array of rows and widgets to be presented when the user clicks on the module within the web interface. Each widget is described by:
      • a size (up to 12 “slots” are available for each row)
      • a layout, e.g. multiple components within the same widgeta. The most common components are:
        • sensor_group_summary: generate a chart with min/max for each sensor of the specified group for today and yesterday
        • image: add an image from a sensor
        • map: generate an interactive map based on the data of a sensor
        • sensor_group_timeline: generate a chart with a timeline of the given timeframe for the sensors belonging to the given group
        • chart_short/chart_short_inverted: generate a chart with a limited size with the data from a single sensor
        • current_header: generate a header with the current measure of a sensor and an icon
        • current_measure: generate a box with the current measure of a sensor
        • alerts: generate a table with all the alerts generated by the platform
        • checkbox: generate a checkbox controlling the given sensor
        • input: add an input form controlling a given sensor
        • separator: add a line separator
        • configuration: add the configuration editor
        • calendar: add a graphical scheduler storing information in a given sensor
        • data: add raw data from a given sensor
        • table: add a table and format data from a given sensor
        • clock: add an analog clock with the current time –
    • rules: array of rules for notifying when a given condition is met. When no condition is specified, the rule will be used by the “oracle” for responding to interactive requests. Each rule is described by:
      • a set of definitions of the data that will be used within the conditions. Each definition extracts from the database one or more values from a given sensor (e.g. yesterday’s average temperature as the latest value of the daily average measures of the outdoor sensor).
      • a set of conditions for comparing dataset defined in the definitions section. All the conditions must be true to have an alert triggering
      • a severity of the alert
      • an time interval for evaluating the conditions (e.g. daily, hourly, every minute, never, etc.)
      • the text of the alert with placeholders from the definitions which will be replaced by the current values

    Plugins

    Each plugin can support input (retrieve data from a sensor), output (send data to an actuator) or both.
    For input, data can be retrived in two ways: pull (the sensor is pulled at regular time intervals) or push (the plugin is kept running and when a new measure is received, the main engine is notified). The following out of the box plugins are part of the software:

    Plugin Name Input Output
    wunderground Yes (pull) No
    weatherchannel Yes (pull) No
    messagebridge Yes (push) Yes
    csv Yes (pull) No
    image Yes (pull) No
    icloud Yes (pull) No
    command Yes (pull) Yes
    system Yes (pull) No
    rtl_433 Yes (push) No
    gpio Yes (pull/push) Yes
    earthquake Yes (pull) No
    mqtt Yes (pull) Yes
    ads1x15 Yes (pull) No
    dht Yes (pull) No
    ds18b20 Yes (pull) No
    rss Yes (pull) No
    mysensors Yes (pull) Yes
    bluetooth Yes (pull) No

    • wunderground: retrieve from Weather Underground the requested measure (e.g. temperature, pressure, weather condition, forecast, etc. review config-schema.json for the full list):
    • weatherchannel: retrieve from Weather Channel weather alerts:
      • set the latitude/longitude in the global plugin configuration or within each plugin settings
      • create a rule to be alerted when the latest weather alert is not empty
    • ** messagebridge**: listen for updates from Wirelessthings/ciseco sensors and read the measure of the configured node:
      • the is no polling interval to configure for this plugin since updates are sent real-time by the wirelessthings messagebridge component.
      • it can also instruct Generic IO firmware to sleep when awake
      • can be used to send messages to a sensor
      • ensure messagebridge is running (https://github.com/WirelessThings/WirelessThings-LaunchPad)
    • csv: parse a csv file
      • it can be used for parsing custom csv files
    • image: retrive an image
      • the image can be either retrived either from a URL or by running a command
      • basic HTTP authentication is supported
      • can be used to retrieve snapshots from the attached raspberry webcam
    • icloud: retrive from icloud the location of an IOS device:
      • run python plugin_icloud.py –username=youricloudemail@email.com to configure the plugin and store the icloud password within the keystore first
      • if family sharing is set up (https://support.apple.com/en-us/HT201060) you will have visibility over all the devices
      • a list of devices to display can be configured
      • The data retrieved can be represented with a “map” type widget. The current position as well the tracking of the last few coordinates will be shown
    • command: execute a command on the raspberry pi to poll a sensor:
      • can be used to poll sensors directly attached to the GPIO of the raspberry pi
    • system: retrieve a system statistic from the raspberry pi:
      • can be selected among a list of pre-defined measures (review the config-schema.json for the full list)
    • rtl_433: run rtl_433 in the background and look for a specific sensor from its output to retrieve a measure
      • rtl_433 turns a Realtek RTL2832 based DVB dongle into a 433.92MHz generic data receiver
      • rtl_433 must be installed from https://github.com/merbanan/rtl_433
      • the device must support a json output
    • gpio: Interact with the raspberry’s GPIO to capture input from the configured pins or send output signals
      • an input pin can be either periodically polled or can automatically trigger when a high/low edge is detected
    • earthquake: retrieve earthquake events from a Federation of Digital Seismograph Network Web Service node
      • Filters can be defined to retrieve only the relevant events
    • mqtt: connect to a mqtt gateway and subscribe for topics.
      • The gateway can be either local or remote
      • can send messages to the gateway
    • ads1x15: retrieve measures from an attached analog to digital converter ads1x15
      • both ADS1115 and ADS1015 are supported
      • output can be the raw measure, a percentage or a voltage
    • dht: retrieve temperature and humidity from an attached DHT11 and DHT22 sensors
    • ds18b20:retrieve the temperature from an attached ds18b20 sensor
    • rss: retrieve news headlines from a RSS feed
    • mysensors: act as a controller to interact with a MySensors (https://www.mysensors.org) gateway and sensors.
      • support multiple serial, ethernet or mqtt gateways
      • support all S & V types
      • support node id generation
      • support smart sleep (outgoing messages are queue and sent to the sensor only once reporting awake)
    • bluetooth: allow polling data from BLE devices.

    For input, “Push” plugins must implement a “run()” method (which will be called at startup to keep the plugin running in background) and a “register(sensor)” method (for registering suitable sensors against the plugin). When a new measure is available, it must call the “store” method of sensors.py to save the data.
    “Pull” plugins must instead implement a “poll(sensor)” method (to retrieve the raw data from the sensor), a “parse(sensor,data)” method (to parse the raw the data previously polled) and optionally a “cache_schema(sensor)” method to cache raw data so preventing different sensors to poll for the same data concurrently. The main engine will be responsible to periodically invoke poll and parse and hence storing the new measure.
    For input plugins, they must implement a “send(sensor,data)” that will be invoked to send a message to their supported actuators.

    Notifications

    The notification subsystem allows the user to communicate with myHouse and viceversa. Each module can support input (the user requests something to the system), output (the system sends the user a notification) or both.
    The following out of the box modules are part of the software:

    Module Input Output
    email No Yes
    sms No Yes
    slack Yes Yes
    audio Yes Yes
    buzzer No Yes
    GSM sms No Yes
    GSM call No Yes

    • email: an email message is sent whenever an alert triggers. Requires a SMTP server configured
    • sms: a SMS message is sent whenever an alert triggers. Requires a Betamax-compatible voip service configured
    • slack: a slack notification is sent whenever an alert triggers. A slack bot connects to a configured team and channel and allows realtime interaction
    • audio: an audio notification is sent to the attached speaker whenever an alert triggers. If a microphone is attached to the system, the user can interacts with it with realtime questions and answers.
    • buzzer: play a tone to an attached active buzzer.
    • GSM sms: a SMS message is sent through an attached GSM module whenever an alert triggers
    • GSM call: a phon call (ring) is placed through an attached GSM module whenever an alert triggers

    For each output notification the following can be optionally set:

    • a minimum severity: only notification with that severity or more critical will be sent through the channel (e.g. send a sms only for critical alerts)
    • a rate limit: maximum number of notifications per hour through that channel (e.g. send maxium 2 sms per hour)
    • a “silent” timeframe: a timeframe in which notifications will be muted (e.g. do not send audio notifications during the night)
    • a minimum severity for the “silent” timeframe: only notification with that severity or more critical will be sent through the channel when muted (e.g. audio notifications are muted during the night but critical alerts will be sent through this channel anyway)

    About myHouse

    Why myHouse?

    There are thousands of home automation suites around and dozens of new solutions made available every single day. So why yet another piece of software? I may have very peculiar requirements but none of the products around had a good fit for me.

    First, I didn’t want to use a cloud-based service both for privacy reasons and because my Internet connection is not necessarily always on so I had the need to both store and present data from within my network.

    Secondarily, I need to review the statistics collected mostly when I am not at home: this is why I had to exclude all the solutions which are creating charts with all the raw data collected if I wanted to avoid high latency and mobile roaming charges. Much lighter and more resistant to spikes looked to me to calculate average/minimum/maximum values for each hour and for each day.

    I also wanted a way to centralize in a single place both the sensors and the webcams, independently of the source. This is why this plugin-based architecture: if you are collecting the external temperature from an Internet service and you add a sensor at home to do the same later, you want to keep the history and use the same presentation format. For the same reason I wanted to be indipendent from the different standards and IoT vendors around.

    I also wanted to create something adapting easily to the extreme flexibility needed by this kind of solutions. This is why everything is defined in the configuration, the sensors you want to collect data from, the widgets to present in the web interface, the way you want each chart to be drawn.

    I also have the need to receive when I’m not at home a very detailed e-mail summary containing the same information as I was browsing the web interface.

    For the same reason (and because I dont’ not want to expose the web interface over the Internet so making the access via the VPN not very handy) I wrote the Slack bot. It allows me to immediate access any information I need in real-time, interact with the actuators (e.g. my boiler) quicker and remotely and, why not, having some fun by arguing with a real bot.

    The last technical requirement I had was to make the solution as lighter as possible (hence Flask instead of Apache/PHP) and gentle with the SD card of my raspberry pi (hence Redis instead of other SQL databases).7

    Need help?

    Third-party software

    myHouse makes use of the following third-party software components:

    Changelog

    • v1.0:
      • Weather module with static sensors
    • v2.0 (for full changelog: https://sourceforge.net/p/my-house/tickets/queue/v2.0/):
      • Added new plugins and enhanced the existing
      • Re-wrote the entire logic and moved from crontab to a builtin scheduler
      • Added alerter module
      • Web interface customizable in terms of widgets and modules
      • Added logging capabilities
      • Added interactive Slack bot
      • Support for multiple data formats
      • Added configuration wizard
      • Added support for imperial measures and fahrenheit temperatures
      • Added support for actuators
      • Added installation and service scripts
      • Added automatic data expiration from the database
    • v2.1 (for full changelog: https://sourceforge.net/p/my-house/tickets/queue/v2.1/):
      • Added a “gpio” plugin to interact with the raspberry’s GPIO for capturing input and sending output signals
      • Added a “rtl_433” plugin to capture measures from generic radio sensor
      • Enhanced the “csv” plugin to support generic csv formatted files
      • Enhanced the “icloud” plugin to display an interactive map and the tracking data of the latest positions
      • Enhanced the rule engine to allow executing the same rule for a set of sensors
      • Consolidated the upgrade script
      • Fixed several bugs
    • v2.2 (for full changelog: https://sourceforge.net/p/my-house/tickets/queue/v2.2/):
      • Added speech recognition and text-to-speech capabilities for realtime voice interaction
      • Added an earthquake module with the capability to retrieve earthquake events from multiple sources, plot them in an interactive map and alert when a strong/close event takes place
      • Multi-language support
      • GUI color skins support
      • Ability to detect motion and objects (e.g. faces) in images
      • Added SMS notifications
      • Added support for MQTT
      • Added a news module with the latest headlines from one or more RSS feeds
      • Added a new module for rebooting/shutting down the hosting system
      • Added new sensor-specific plugins: ads1x15, dht, ds18b20
      • Added map tracking options to the icloud plugin
      • Added linear regression statistics
      • Added new UI widgets: configurable button
      • Added per-sensor data retention options
      • Added ability to upload data to a Wundergound PWS
      • Bug fixes and minor enhancements
    • v2.3 (for full changelog: https://sourceforge.net/p/my-house/tickets/queue/v2.3/):
      • Added support for MySensors serial, ethernet and mqtt gateways
      • Added support for Bluetooth Low Energy (BLE) sensors
      • Included a simpler, fully working example configuration file
      • Improved installation and upgrade scripts
      • Bug fixes and minor enhancements
    • v2.4 (for full changelog: https://sourceforge.net/p/my-house/tickets/queue/v2.4/):
      • Added support for SMS/phone call notifications through an attached GSM module
      • Added support for activating a buzzer when an alert triggers
      • Added support for Orange Pi GPIO
      • Added support for running on a generic debian-based linux distribution
      • Enhanced the scheduler’s flexibility
      • Enhaced the rule-based engine’s capabilities
      • Added additional backup options
      • Bug fixes and minor enhancements

    Visit original content creator repository
    https://github.com/myhouse-project/myHouse

  • shopify_api

    shopify_api

    crates.io Documentation MIT/Apache-2 licensed CI Issues

    An ergonomic, Shopify API Client for Rust.

    • GraphQL API support with automatic data deserialization
    • Changelog

    Example

    This asynchronous example uses Tokio and enables some optional features, so your Cargo.toml could look like this:

    [dependencies]
    shopify_api = "0.8"
    tokio = { version = "1", features = ["full"] }

    And then the code:

    use shopify_api::*;
    use shopify_api::utils::ReadJsonTreeSteps;
    use serde::{Deserialize};
    
    #[derive(Deserialize)]
    struct Shop {
      name: String,
    }
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let shopify = Shopify::new("hello", "world", String::from("2024-04"), None);
    
      let graphql_query = r#"
        query {
          shop {
          name
         }
      }"#;
    
      let variables = serde_json::json!({});
      let json_finder = vec![ReadJsonTreeSteps::Key("data"), ReadJsonTreeSteps::Key("shop")];
    
      let shop: Shop = shopify.graphql_query(graphql_query, &variables, &json_finder).await.unwrap();
      Ok(())
    }

    Or with the new GraphQl Client!

    [dependencies]
    shopify_api = "0.89"
    tokio = { version = "1", features = ["full"] }
    graphql_client = "0.14.0"
    query GetShop {
      shop {
        name
      }
    }
    use shopify_api::*;
    use graphql_client::GraphQLQuery;
    
    #[derive(GraphQLQuery)]
    #[graphql(
        schema_path = "./graphql.schema.json",
        query_path = "graphql/getShop.graphql",
        response_derives = "Debug"
    )]
    struct GetShop;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let shopify = Shopify::new("hello", "world", String::from("2024-04"), None);
    
      let shop_info = connector
            .shopify
            .post_graphql::<GetShop>(get_shop::Variables {})
            .await;
    
      Ok(())
    }

    Download the graphql schema

    You can download one from this repository

    Or download it from the Shopify Graphql API with the following command

    Warning

    Sometimes you’ll get an error with the GraphQLQuery derive caused my a missing struct, most of the time, you can fix it by adding the missing struct by importing it from the types import or you can create a new struct with the same name as the missing one, and the derive will work.

    License

    Licensed under MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

    Visit original content creator repository https://github.com/0xtlt/shopify_api
  • shopify_api

    shopify_api

    crates.io Documentation MIT/Apache-2 licensed CI Issues

    An ergonomic, Shopify API Client for Rust.

    • GraphQL API support with automatic data deserialization
    • Changelog

    Example

    This asynchronous example uses Tokio and enables some optional features, so your Cargo.toml could look like this:

    [dependencies]
    shopify_api = "0.8"
    tokio = { version = "1", features = ["full"] }

    And then the code:

    use shopify_api::*;
    use shopify_api::utils::ReadJsonTreeSteps;
    use serde::{Deserialize};
    
    #[derive(Deserialize)]
    struct Shop {
      name: String,
    }
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let shopify = Shopify::new("hello", "world", String::from("2024-04"), None);
    
      let graphql_query = r#"
        query {
          shop {
          name
         }
      }"#;
    
      let variables = serde_json::json!({});
      let json_finder = vec![ReadJsonTreeSteps::Key("data"), ReadJsonTreeSteps::Key("shop")];
    
      let shop: Shop = shopify.graphql_query(graphql_query, &variables, &json_finder).await.unwrap();
      Ok(())
    }

    Or with the new GraphQl Client!

    [dependencies]
    shopify_api = "0.89"
    tokio = { version = "1", features = ["full"] }
    graphql_client = "0.14.0"
    query GetShop {
      shop {
        name
      }
    }
    use shopify_api::*;
    use graphql_client::GraphQLQuery;
    
    #[derive(GraphQLQuery)]
    #[graphql(
        schema_path = "./graphql.schema.json",
        query_path = "graphql/getShop.graphql",
        response_derives = "Debug"
    )]
    struct GetShop;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let shopify = Shopify::new("hello", "world", String::from("2024-04"), None);
    
      let shop_info = connector
            .shopify
            .post_graphql::<GetShop>(get_shop::Variables {})
            .await;
    
      Ok(())
    }

    Download the graphql schema

    You can download one from this repository

    Or download it from the Shopify Graphql API with the following command

    Warning

    Sometimes you’ll get an error with the GraphQLQuery derive caused my a missing struct, most of the time, you can fix it by adding the missing struct by importing it from the types import or you can create a new struct with the same name as the missing one, and the derive will work.

    License

    Licensed under MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

    Visit original content creator repository https://github.com/0xtlt/shopify_api